一、简单介绍
XStream是thoughtworks开发的开源框架,用于实现XML数据于Java对象、Json数据的转换。它不需要schema或其他的mapping文件就可以进行java对象和xml文件之间的转换,API调用起来非常方便,并且扩展功能强大。
1,XStream的特点
a)灵活易用:在更高的层次上提供了简单、灵活、易用的统一接口,用户无需了解项目的底层细节
b)无需映射:大多数对象都可以在无需映射的情况下进行序列化与反序列化的操作
c)高速稳定:设计时力求达到的最重要的指标是解析速度快、占用内存少,以使之能够适用于大的对象处理或是对信息吞吐量要求高的系统
d)清晰易懂:项目采用reflection机制得到无冗余信息的XML文件。所生成的XML文件较本地Java序列化产物更简洁,格式更清晰,更便于用户阅读
e)无需修改:完全序列化包括private和final类型在内的全部内部字段。支持非公有类和内部类,类可以没有缺省的构造函数。
f)易于集成:通过实现特定的接口,XStream可以直接与其它任何树型结构进行序列化与反序列化操作(而不仅仅是XML格式)
g)灵活转换:转换策略是可以定制的,允许用户自定义特殊类型的对象如何以XML格式存储。
h)错误处理:由于XML文本不合法而造成异常时,会提供详细地诊断信息帮助处理问题。
2,应用场合
a)数据对象的持久化
b)数据交换
c)配置文件
3,架构分析
a)Converters(转换器)
当XStream遇到需要转换的对象时,它会委派给合适的转换器实现,XStream为通用类型提供了多种转换器实现,包括基本数据类型、String、Collections、Arrays、null、Date,等等。
XStream提供了缺省的转换器,当需要转换的数据对象没有匹配的转换器时会使用。是通过反射机制自动完成对对象内所有字段的映射。
b)IO(输入/输出)
XStream是通过接口HierarchicalStramWriter和HierarchialStreamReader从底层XML数据中抽象而来的,上面的接口分别用于序列化和反序列化操作。
该特性使得XStream可以直接使用XML解析类从数据流中读取数据,或者是直接从已经存在的结构中提取数据(比如DOM)。如果XStream所操作的 XML数据已经部分被其它XML解析类处理过了(比如SOAP类的实例),这样就可以避免在我们这一层的再次解析操作。
c)Context(上下文引用)
在XStream序列化或反序列化对象时,它会创建两个类MarshallingContext和UnmarshallingContext,由它们来处理数据,以及委派合适的转换器。
XStream提供了三对上下文的缺省实现,它们之间有着细微的差别。缺省值可以通过方法XStream.setMode()来改变,需要传递下面参数中的一个:
i)XStream.XPATH_REFERENCES,(缺省的)通过XPath引用来标识重复的引用。这样产生的XML具有最小的混乱性。
ii)XStream.ID_REFERENCES,使用ID引用来标识重复的引用。在一些场合,比如使用手写XML时,这样将会更易于操作
iii)XStream.NO_REFERENCES,这种情况将失去对图形对象的支持,仅把对象看作为树型结构。重复的引用被视作两个不同的对象,循环引用会导致异常产生。相对于上面两种模式,这种模式速度会更快,占用内存会更
d)Facade(统一入口)
主要类XStream用作所有项目的入口点。它将上面所提及的重要组件集成在一起,提供更简单易用的API操作。
二、资源网址
项目主页:
http://xstream.codehaus.org/
在线帮助文档:http://xstream.codehaus.org/javadoc/index.html
lib和源码下载:http://xstream.codehaus.org/download.html
?
三、注意事项:
1,XStream将Java对象序列化为XML数据时,不关心属性字段是否是final、private类型,也不关心是否有对应的get/set方法,更不关心你是否有一个默认的无参构造方法。
2,项目的classpath中应该有3个包:xstream-[版本].jar,xpp3-[版本].jar,xmlpull-[版本].jar。
(以上来源于http://www.cxyclub.cn/n/26185/)
四、使用入门示例及介绍
准备工作x-stream.jar、xmlpull.jar、xpp3.jar
第1步:创建XStream对象。
通过它传递一个StaxDriver创建XStream对象。StaxDriver使用SAX解析器(可从Java6),一个快速的XML解析器。
//这样创建XStream实例时,上面那3个jar包必须都有 XStream xstream = new XStream(); //这里不需要XPP3库了,而是使用标准的JAXP DOM解析XML XStream xstream = new XStream(new DomDriver()); //这里不需要XPP3库了但是需要你使用java 6 XStream xstream = new XStream(new StaxDriver()); <span style="background-color: rgb(255, 102, 102);">根据需要找一种合适的创建方式</span>
第2步:序列化对象到XML。
使用toXML() 方法来获取对象的XML字符串表示。
String xml = xstream.toXML(student);
第3步:反序列化XML获得对象。
使用 fromXML()方法来从XML对象。
Personsstudent1 = (Persons)xstream.fromXML(xml);
package com.xstream.vo1;
public class Address {
private String addType;
private String place;
public Address(String addType, String place) {
this.addType = addType;
this.place = place;
}
public String getAddType() {
return addType;
}
public void setAddType(String addType) {
this.addType = addType;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
public String toString() {
return "Address{" +
"addType='" + addType + '\'' +
", place='" + place + '\'' +
"}\n";
}
}
package com.xstream.vo1;
import java.util.Iterator;
import java.util.List;
public class Addresses {
private List<Address> listAdd;
public Addresses(List<Address> listAdd) {
this.listAdd = listAdd;
}
public List<Address> getListAdd() {
return listAdd;
}
public void setListAdd(List<Address> listAdd) {
this.listAdd = listAdd;
}
public String toString() {
StringBuffer sb=new StringBuffer();
for(Iterator it=listAdd.iterator();it.hasNext();){
Address add=(Address)it.next();
sb.append(add.toString());
}
return "Addresses{" +
"listAdd=" + sb.toString() +
"}\n";
}
}
package com.xstream.vo1;
public class Person {
private String name;
private String sex;
private String tel;
private Addresses addes;
public Person(Addresses addes, String name, String sex, String tel) {
this.addes = addes;
this.name = name;
this.sex = sex;
this.tel = tel;
}
public Addresses getAddes() {
return addes;
}
public void setAddes(Addresses addes) {
this.addes = addes;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String toString() {
return "Person{" + "addes=" + addes.toString() + ", name='" + name
+ '\'' + ", sex='" + sex + '\'' + ", tel='" + tel + '\''
+ "}\n";
}
}
package com.xstream.vo1;
import java.util.Iterator;
import java.util.List;
public class Persons {
private String type;
private List<Person> listPerson;
public Persons(List<Person> listPerson, String type) {
this.listPerson = listPerson;
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Person> getListPerson() {
return listPerson;
}
public void setListPerson(List<Person> listPerson) {
this.listPerson = listPerson;
}
public String toString() {
StringBuffer sb=new StringBuffer();
for(Iterator it=listPerson.iterator();it.hasNext();){
Person p=(Person)it.next();
sb.append(it.toString());
}
return "Persons{" +
"type='" + type + '\'' +
", listPerson=" + sb.toString() +
"}\n";
}
}
package com.xstream.demo1;
import java.util.ArrayList;
import java.util.List;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.xstream.vo1.Address;
import com.xstream.vo1.Addresses;
import com.xstream.vo1.Person;
import com.xstream.vo1.Persons;
public class XStreamDemo {
public static void main(String args[]) {
testBean2XML();
}
/**
* 生成一个Persons对象
*
* @return Persons对象
*/
public static Persons getPersons() {
Address add1 = new Address("type1","人民广场1");
Address add2 = new Address("type2","人民广场2");
List<Address> addlist1 = new ArrayList<Address>();
addlist1.add(add1);
addlist1.add(add2);
Address add3 = new Address("type3","人民广场3");
Address add4 = new Address("type4","人民广场4");
List<Address> addlist2 = new ArrayList<Address>();
addlist2.add(add3);
addlist2.add(add4);
Addresses addes1 = new Addresses(addlist1);
Addresses addes2 = new Addresses(addlist2);
Person person1 = new Person(addes1, "6666554", "lavasoft", "man");
Person person2 = new Person(addes2, "7777754", "yutian", "man");
List<Person> listPerson = new ArrayList<Person>();
listPerson.add(person1);
listPerson.add(person2);
Persons persons = new Persons(listPerson,"001");
return persons;
}
/**
* 利用XStream在Java对象和XML之间相互转换
*/
public static void testBean2XML() {
System.out.println("Java==》xml");
Persons persons = getPersons();
XStream xstream = new XStream(new DomDriver());
System.out.println(xml);
System.out.println("xml==》Java对象");
Persons cre_person = (Persons) xstream.fromXML(xml);
System.out.println(cre_person.toString());
}
}
运行结果:
Java==》xml
<com.xstream.vo1.Persons>
<type>001</type>
<listPerson>
<com.xstream.vo1.Person>
<name>6666554</name>
<sex>lavasoft</sex>
<tel>man</tel>
<addes>
<listAdd>
<com.xstream.vo1.Address>
<addType>type1</addType>
<place>人民广场1</place>
</com.xstream.vo1.Address>
<com.xstream.vo1.Address>
<addType>type2</addType>
<place>人民广场2</place>
</com.xstream.vo1.Address>
</listAdd>
</addes>
</com.xstream.vo1.Person>
<com.xstream.vo1.Person>
<name>7777754</name>
<sex>yutian</sex>
<tel>man</tel>
<addes>
<listAdd>
<com.xstream.vo1.Address>
<addType>type3</addType>
<place>人民广场3</place>
</com.xstream.vo1.Address>
<com.xstream.vo1.Address>
<addType>type4</addType>
<place>人民广场4</place>
</com.xstream.vo1.Address>
</listAdd>
</addes>
</com.xstream.vo1.Person>
</listPerson>
</com.xstream.vo1.Persons>
xml==》Java对象
Persons{type='001', listPerson=java.util.AbstractList$Itr@95fd19java.util.AbstractList$Itr@95fd19}