Castor XML
Castor XML作为一个数据绑定框架,可以实现任何类似Java Bean的对象和XML文档表示之间的相互转换。通常情况下,Castor使用一组类描述
符(ClassDescriptor)和字段描述符(FieldDescriptor)集来定义一个Java对象如何编组(Marshall)成XML数据或者从XML数据解编
(Unmarshall)为Java对象。
XML编组(Marshalling)框架
XML编组框架实现Java对象与XML文档间的相互转换。在下文中,除非显式提及,否则编组框架指编组和解编两种功能。Castor XML编组框架包
含在两个主要的类org.exolab.castor.xml.Marshaller和org.exolab.castor.xml.Unmarshaller中。
1自省方式(introspection)的编组与解编
下面我们通过一个简单的示例展示XML编组框架以自省的方式在Java对象与XML文档之间转换的功能。首先,定义一个简单的Person类,该类包
含两个字段:name和 birthday,分别指定义某个人的名字和出生日期。Person类定义如下:
import java.util.Date;
/**Ansimplepersonclass*/
public class Person implements java.io.Serializable {
/**The name of the person**/
private String name = null;
/**TheDateofbirth*/
private Date birthday = null;
/**CreatesaPersonwithnoname*/
public Person() {}
/**CreatesaPersonwiththegivenname*/
public Person(String name) {
this.name = name;
}
/**
*@returndateofbirthoftheperson
*/
public Date getDateOfBirth() {
returnbirthday;
}
/**
*@returnnameoftheperson
*/
public String getName() {
returnname;
}
void setDateOfBirth(Date birthday) {
this. birthday = birthday;
}
/**
*Setsthenameoftheperson
*@paramnamethenameoftheperson
*/
publicvoid setName(String name) {
this.name = name;
}
}
然后,我们定义一个Person类的实例并将其编组输出为XML,示例代码如下:
// 创建一个新的Person对象
Person person = new Person("Ryan 'Mad Dog' Madden");
Calendar birthday = new GregorianCalendar(1955, 8, 15);
person.setDateOfBirth(birthday.getTime());
// 构建编组后的XML文档输出
FileWriter writer = new FileWriter("d:\\test.xml");
Marshaller.marshal(person, writer);
下面的代码读取上述输出的XML文档并将解编为Java对象:
// 构建输入XML文档的Reader
FileReader reader = new FileReader("d:\\test.xml");
// 解编XML文档为Person对象
person = (Person) Unmarshaller.unmarshal(Person.class, reader);
System.out.println("Name="+person.getName());
3.1.2 使用映射文件方式的编组与解编
调用Marshaller和Unmarshaller的实例方法时,必须提供XML文档结构和Java类模型间的映射定义文件。关于Mapping映射文件的定义我们会在
下述章节中给出详细介绍。下面是调用Marshaller和Unmarshaller的实例方法的代码示例:
// 加载映射文件
Mapping mapping = new Mapping();
mapping.loadMapping("mapping.xml");
// 为待解编的XML文档构建一个Reader
reader = new FileReader("test.xml");
// 构建一个解编器 Unmarshaller
Unmarshaller unmarshaller = new Unmarshaller(Person.class);
unmarshaller.setMapping(mapping);
// 解编XML文档为Person对象
Person person = (Person) unmarshaller.unmarshal(reader);
调用Marshaller和Unmarshaller的实例方法时,必须提供XML文档结构和Java类模型间的映射定义文件。
注意:当使用Marshaller和Unmarshaller的静态方法时,即使指定了映射定义文件,此映射定义也会被忽略。
3.2Castor XML的编组/解编机制
Castor通过类描述符和字段描述符几乎可以编组/解编所有的Java对象。当某个Java对象类描述符不存在时,编组框架通过使用反射
(Reflection)方式获取对象的结构信息,并在内存中为此对象构造类描述符和字段描述符。当实体类的描述符存在时,Castor使用这些描述
符提供的Java对象模型信息用来处理编组和解编。
编组与解编过程中,Castor要求实体类定义必须提供”public”类型的默认构造函数(不含参数)声明以及必要的”getter”和”setter”方
法。
3.2.1 类描述符
类描述符(org.exolab.castor.xml.XMLClassDescriptor)使得编组框架具有足够的信息以正确的处理编组/解编过程。在Castor中,类描述符由
XML编组框架和JDO框架(后文详细描述)共享。每个类描述符包含一组字段描述符(org.exolab.castor.xml.XMLFieldDescriptor)。
XML 类描述符具有两种构建方式:编译时构建和运行时构建。
l 编译时构建描述符
在编译时构建类描述符,一种方法是为每一个需要编组的实体类实现org.exolab.castor.xml.XMLClassDescriptor接口;另一种方式是使用
Castor提供的源代码生成器通过XML Schema定义文档在生成Java实体类定义的同时,为Java实体类生成相应的类描述符。
编译时构建类描述符的方式的主要优点是其执行速度快于运行时构建方式。
l 运行时构建描述符
使用运行时构建类描述符时,Castor可以直接通过反射自省方式Java实体类,也可以提供映射定义文件。这两种方式可以结合使用。对于默认
的自省方式,实体类必须为必要的字段提供适当的setter/getter方法;如果没有给编组的字段数据指定setter/getter方法,Castor只能访问
类型为”public”的字段。如果上述条件都不满足,Castor将不处理上述字段。
在Castor中,自省方式默认启动,不需要做任何设置。用户可以在castor.properties文件中设定必要的参数来控制自省方式的行为,如字段命
名惯例,原始类型默认看作XML属性还是节点(Element)。用户可以查看castor.properties文件(在Castor发布Jar包中的”
org/exolab/castor”路径下)获取详细信息。
使用映射文件描述实体类时,用户需要在编组/解编操作前加载映射定义。映射定义参考(org.exolab.castor.mapping.Mapping)。
3.3使用XMLContext获取编组器和解编器
Castor自 V1.1.2版本开始在XML编组框架中提供了XMLContext类,用于方便高效的获取Marshaller和Unmarshaller实例。上述3.1节中编组解编
Person类实例的例子使用XMLContext实现的方式如下:
import org.exolab.castor.xml.XMLContext;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.xml.Unmarshaller;
// 构建Mapping实例
Mapping mapping = XMLContext.createMapping();
mapping.loadMapping("mapping.xml");
// 构建一个XMLContext实例并设定映射
XMLContext context = new XMLContext();
context.addMapping(mapping);
// 构建一个Unmarshaller
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setClass(Person.class); // 为待解编的XML文档构建一个Reader
Reader reader = new FileReader("test.xml");
// 从XML文档中解编person对象
Person person = (Person) unmarshaller.unmarshal(reader);
如上述代码所示,XMLContext提供了不同的工厂方法用于获取新的Marshaller,Unmarshaller和Mapping实例。当在一个应用中需要使用不止一
个Unmarshaller实例时,可以根据需要调用XMLContext的createUnmarshaller实例方法。从同一个XMLContext实例获取多个Unmarshaller实例
时开销很小。需要注意的是,Unmarshaller不是线程安全的。