开源项目Xstream简介 ---用于序列化对象与XML对象之间的相互转换 开源项目Xstream简介 目录
项目简介 开源项目XStream是一套简单实用的类库,用于序列化对象与XML对象之间的相互转换。本文以XStream 1.1.2版进行说明,它具有以下几个特点:
典型的应用场合 XStream主要应用于以下场合:
XStream系统架构分析 XStream的架构主要由四部分组成: Converters(转换器) 当XStream遇到需要轮换的对象时,它会委派给合适的转换器实现,XStream为通用类型提供了多种转换器实现,包括基本数据类型、String、Collections、Arrays、null、Date,等等。 XStream提供了缺省的转换器,当需要转换的数据对象没有匹配的转换器时会使用。是通过反射机制自动完成对对象内所有字段的映射。 IO(输入/输出) XStream是通过接口HierarchicalStramWriter和HierarchialStreamReader从底层XML数据中抽象而来的,上面的接口分别用于序列化和反序列化操作。 该 特性使得XStream可以直接使用XML解析类从数据流中读取数据,或者是直接从已经存在的结构中提取数据(比如DOM)。如果XStream所操作的 XML数据已经部分被其它XML解析类处理过了(比如SOAP类的实例),这样就可以避免在我们这一层的再次解析操作。 Context(上下文引用) 在XStream序列化或反序列化对象时,它会创建两个类MarshallingContext和UnmarshallingContext,由它们来处理数据,以及委派合适的转换器。 XStream提供了三对上下文的缺省实现,它们之间有着细微的差别。缺省值可以通过方法XStream.setMode()来改变,需要传递下面参数中的一个: XStream.XPATH_REFERENCES (缺省的)通过XPath引用来标识重复的引用。这样产生的XML具有最小的混乱性。 XStream.ID_REFERENCES 使用ID引用来标识重复的引用。在一些场合,比如使用手写XML时,这样将会更易于操作 XStream.NO_REFERENCES 这种情况将失去对图形对象的支持,仅把对象看作为树型结构。重复的引用被视作两个不同的对象,循环引用会导致异常产生。相对于上面两种模式,这种模式速度会更快,占用内存会更 Facade(统一入口) 主要类XStream用作所有项目的入口点。它将上面所提及的重要组件集成在一起,提供更简单易用的API操作。 实例讲解 下面我们通过一个简单的例子来了解XStream是如何工作的。 创建需要序列化的对象类 /**个人信息类*/ public class Person { /** * 构造函数 * @param fn 名称前部分 * @param ln名称后部分 * @param faxn 传真号码 * @param mobilen 移动电话 */ public Person(String fn, String ln, PhoneNumber faxn, PhoneNumber mobilen) { this.firstName = fn; this.lastName = ln; this.faxNumber = faxn; this.mobileNumber = mobilen; } /** * 构造函数 * @param fn 名称前部分 * @param ln名称后部分 */ public Person(String fn, String ln) { this.firstName = fn; this.lastName = ln; } private String firstName; private String lastName; private PhoneNumber faxNumber; private PhoneNumber mobileNumber; /** * @return Returns the faxNumber. */ public PhoneNumber getFaxNumber() { return faxNumber; } /** * @param faxNumber * The faxNumber to set. */ public void setFaxNumber(PhoneNumber faxNumber) { this.faxNumber = faxNumber; } /** * @return Returns the firstName. */ public String getFirstName() { return firstName; } /** * @param firstName * The firstName to set. */ public void setFirstName(String firstName) { this.firstName = firstName; } /** * @return Returns the lastName. */ public String getLastName() { return lastName; } /** * @param lastName * The lastName to set. */ public void setLastName(String lastName) { this.lastName = lastName; } /** * @return Returns the mobileNumber. */ public PhoneNumber getMobileNumber() { return mobileNumber; } /** * @param mobileNumber * The mobileNumber to set. */ public void setMobileNumber(PhoneNumber mobileNumber) { this.mobileNumber = mobileNumber; } } /**电话号码信息类*/ public class PhoneNumber { private int phoneId; private String phoneNumber; /** * 构造函数 * @param phoneId ID号码 * @param phoneNumber 电话号码 */ public PhoneNumber(int phoneId, String phoneNumber) { super(); this.phoneId = phoneId; this.phoneNumber = phoneNumber; } /** * @return Returns the phoneNumber. */ public String getPhoneNumber() { return phoneNumber; } /** * @param phoneNumber * The phoneNumber to set. */ public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } /** * @return Returns the phoneId. */ public int getPhoneId() { return phoneId; } /** * @param phoneId * The phoneId to set. */ public void setPhoneId(int phoneId) { this.phoneId = phoneId; } } 这 里定义的属性都为private,XStream没有强制规定属性的可见性,默认情况下所有属性都会进行转换;虽然XStream不强制要求你必须要有 setter和getter方法,也不要求你要有一个默认的类构造方法,但是在实际应用时,这些还是必须的,因为你在程序中需要为对象设置属性,需要构造 对象,如果没有这些方法程序是不能编译通过的。 初始化XStream类 使用以下的语句进行初始化操作: XStream xstream = new XStream(); 默认情况下,XStream会采用Xpp3库,XPP3是一种运行效率非常高的XML全解析实现。如果你不想依靠Xpp3库的话,也可以使用一个标准的JAXP DOM解析器,可以采用以下语句进行初始化: //不使用XPP3库 XStream xstream = new XStream(new DomDriver()); 此xstream实例,为线程安全的,可以供多个线程进行调用,共享使用。参考com.thoughtworks.xstream.io.xml包,会发现系统提供了多种标识解析器供我们选择,包括,DomDriver、JDomDriver、StaxDriver等等。 注册需要转换的类的别名 现在,为了使XStream输出的XML文件更简练,我们要为需要转换的用户类设置别名,这些明会在转换过程中用于结点设置,注册别名使用以下的语句: xstream.alias(“person”, Person.class); xstream.alias(“phonenumber”, PhoneNumber.class); 当然,这一步不是必须的,如果不进行注册的话,XStream默认会在转换时,将用户类的全限定名称加入到XML文件中,如com.test.Person,如果在数据量较大的时候,生成的XML文件会增大不少。 将对象序列化为XML文档 到了这一步,我们就可以将一个Java对象序列化为XML文档了,先声明一个Person对象,然后为该对象设置一个手机号码,一个传真号码,使用下面的语句: //生成Person对象,并注册属性 Person joe = new Person("Bill", "Gates"); joe.setFaxNumber(new PhoneNumber(101, "83501194")); joe.setMobileNumber(new PhoneNumber(102, "13686447788")); 下面就是将生成的对象序列化,我们需要做的只是简单的使用下面的一个语句就可以: String xmls = xstream.toXML(joe); 从结果我们可以看出,生成的XML文件非常简洁,除了必要的结点外,没有一丝多余的信息存在。参考下面的生成结果: <person> <firstName>Bill</firstName> <lastName>Gates</lastName> <faxNumber> <phoneId>101</phoneId> <phoneNumber>83501194</phoneNumber> </faxNumber> <mobileNumber> <phoneId>102</phoneId> <phoneNumber>13686447788</phoneNumber> </mobileNumber> </person> 从XML文件反序列化成对象 从一个XML文件反序列化出一个对象同样简单,一起来看下面的代码: Person newJoe = (Person)xstream.fromXML(xmls); 结束语 通过上面的实例,我们可以看出,使用XStream来处理对象的序列化和反序列化很简单,只需要几行代码即可,而且该项目对标识的XML解析器有很好的支 持,最重要的是生成的XML很“干净”,没有过多的冗余信息,该项目还在持续进行中,让我们一起来关注它吧! 参考资料 XStream官方资料 http://xstream./index.html |
|
来自: shaobin0604@1... > 《Java》