XStream
1. XStream 是 JavaBean 和 XML 转换
2. XStream 并不关心字段的可见性 没有getter/setter
相关: XPP3 是非常快的 pull-parse
包: xstream-[版本].jar xpp3-[版本].jar
使用Xstream,使用如下代码实例化XStream类。
Xstream xstream = new XStream();
不使用XPP3
XStream xstream = new XStream(new DomDriver()); //dos not require XPP3 library
对自己的的类名创建别名使得生成的XML元素更加简洁(可选)
xstream.alias("person",Person.class);
xstream.alias("phonenumber",PhoneNumber.class);
创建Person的实例
Person joe = new Person("joe","Walnes");
joe.setPhone(new PhoneNumber(123,"1234-456"));
joe.setFax(new PhoneNumber(123,"9999-999"));
将 Person 对象序列化 为XML,只需调用XStream对象的toXML(Object)方法
String xml = xstream.toXML(joe);
从XML反序列化至对象
Person newJoe = (Person)xstream.fromXML(xml);
快速小结:
1) xstream.alias(String elementName, Class class);
该方法创建自定义类名所对应XML元素的名称
2) xstream.toXML(Object object);
该方法用于将传入的JavaBean对象序列化为XML字符串并返回
3) xstream.forXML(String xml);
该方法用于将传入的XML字符串反向序列化为JavaBean对象
aliasField(String 字段别名, Class 类定义, String 字段名);
2.1 类别名
Xstream xstream = new Xstream();
String xml = xstream.toXML(obj);
上面代码将对象obj序列化为XML,默认情况下,将一个类的对象序列化为XML,
则该类所对应的XML元素名称会以类全名(包名+类名)的方式命名,
如Person类的包名为com.thoughtworks,那么Person实例所序列化的XML元素名称将为:
<com.thoughtworks.Person> …… </ com.thoughtworks.Person >
显然,这种方式所生成的XML不够简洁,也不利于人工阅读,所以XStream给我们提供了类别名来解决这一问题,
xstream.alias(String 类别名, Class 类定义);
如:我们使用如下代码将Person类定义别名
xstream.alias(“person”, Person.class);
这样我们生成的XML字符串就会变成<person>…</person>;
注意:
当生成XML时指定了类的别名,在读取生成的XML转换为对象时,也需要为其指定别名,
否则XStream将无法识别,字段、属性、包别名都是同样如此,下不赘述。
2.2 字段别名
和类别名同样的道理,类的字段也可以定义别名。
aliasField(String 字段别名, Class 类定义, String 字段名);
如Person类有字段firstName,我们想在生成的XML中将此字段名改为first,则我们可以使用如下代码:
xstream.aliasField("first", Person.class, "firstName");
则生成的XML为:<Person><first>...</first>...
2.3 属性别名
XStream可以将对象的字段映射为XML元素的属性:
useAttributeFor(Class define din, String fieldnames);
并且可以为指定的属性指定别名:
aliasAttribute(Class 类定义, String 属性名, String 属性别名);
xstream.aliasAttribute(Person.class, "");
<Person FirstName=”xusweeter”>....
注意:
读取XML属性时,需要使用如下方法将属性映射为类的字段,否则XStream将不做任何处理。
useAttributeFor(Class 类定义, String 字段名);
2.4 包别名
Xstream还可以对类的包名指定别名。
aliasPackage(String name, String pkgName)
原来的包名为com.thoughtworks,经过如下代码修改为org.thoughtworks。
aliasPackage(“org.thoughtworks”, com.thoughtworks);
叁、集合说明
JavaBean中会经常用到集合对象,如List,刚开始学习时,对于集合总是感觉无从下手,经过琢磨,对其有大体的了解,特别说明一下。
首先我们构建一个包含集合字段的类:
public class Blog {
private List articles;
public void add(String article){
this.articles.add(article);
}
}
我们创建一个Blog对象,并填充它的字段。
Blog blog = new Blog();
blog.add("chapter1");
blog.add("chapter2");
将此对象序列化为XML:
XStream xstream = new XStream();
System.out.println(xstream.toXML(blog));
我们将会得到如下XML:
<collection.Blog>
<articles>
<string>chapter1</string>
<string>chapter2</string>
</articles>
</collection.Blog>
着色的部分就是集合字段生成的XML,所以我们看到有重复的相同标签的XML元素就应当和集合建立联系,实验证明使用代码:
Blog blog1 = (Blog)xstream.fromXML(xstream.toXML(blog));
可以将上述生成的XML反向序列化为Blog对象。
3.1 隐含集合:
另外,XStream类为我们提供了另外一个方法:
addImplicitCollection(Class ownerType, String fieldName)
该方法的作用是引入隐含集合(Implicit Collection),即某个类包含集合字段,引入隐含集合方法可以在生成的XML中并不显示集合字段的标签。
如:加入如下代码xstream.addImplicitCollection(Blog.class, "articles")生成的XML如下:
<collection.Blog>
<string>chapter1</string>
<string>chapter2</string>
</collection.Blog>
和之前的XML比较发现少了<articles></articles>标签,这就是隐含集合。要特别注意,上面的两个<string>标签并不是Blog类的两个别名为string的字段,而是一个集合字段的内容;所以再次强调,如果发现有紧邻的重复标签,要把它们看作是集合的内容,而不是多个字段(事实上也无法解析为含有多个相同名称的字段)。
肆、对象引用
在Java中经常会碰到对象引用的情况,如定义了一个对象A,B对象会引用对象A。那么在对象引用发生时,在序列化的XML中该如何表述呢?
XStream在XML中能够通过相对XPath、绝对XPath或者IDs模式表示对象之间的引用关系。模式可以通过方法setMode(int)来更改。通过引用可以简短XML代码量,避免冗余,但是降低了可阅读性。
XStream的模式:
l XStream.XPATH_RELATIVE_REFERENCES(默认)
默认的引用方式,通过XPath的相对位置来引用
l XStream.XPATH_ABSOLUTE_REFERENCES
绝对引用方式
l XStream.ID_REFERENCES
ID引用方式,通过对元素编号来引用
l XStream.NO_REFERENCES
无引用方式
下面我们来构建一个示例来说明各种引用方式,比如有如下引用:
List order = new ArrayList();
order.add(bj);
order.add(bj);
order.add(order);
一个集合order,连续两次添加了同一个对象,最后又把自身添加进去,详细的类定义见官网“Object References”章节。
4.1 XPath相对引用
XStream在默认的情况下是以XPATH_RELATIVE_REFERENCES模式来表示对象间的引用关系。
XStream xstream = new XStream();
System.out.println(xstream.toXML(order));
生成的XML结果如下:
<list>
<CD>
<id>Next Road Cross</id>
</CD>
<CD reference="../CD"/>
<list reference=".."/>
</list>
请注意上面着色和加粗部分的引用是以自身和目标的相对关系来引用的。
4.2 XPath绝对引用
XPath绝对引用模式下是以根节点开始直到目标对象的结构关系来引用的,修改XStream的模式:
xStream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
得到结果如下,请注意加粗着色部分的代码:
<list>
<CD>
<id>Next Road Cross</id>
</CD>
<CD reference="/list/CD"/>
<span style