如果你的程序中使用到了XML或者JSON,那么你应该对这个库有兴趣。官方的说法是:XStream是一个能够将对象序列化为XML并且反序列化回来的类库。
官方网站是:http://xstream.codehaus.org/
1. 配置
Maven下配置非常简单,仅需要添加两个Dependency:
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>${jettison.version}</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>${xstream.version}</version>
</dependency>
2. 编写最简单的测试程序
可以使用代码控制实体到XML(或反序列化)的格式,但这里我强烈推荐使用注解,因为看起来程序更加整洁,也较容易理解:
2.1 实体类
我们的最简单的实体类可以是这样的:
@XStreamAlias("simplePerson")
public class SimplePerson {
@XStreamAlias("firstName")
private String firstName;
@XStreamAlias("lastName")
private String lastName;
@XStreamAlias("telphone")
private PhoneNumber tel;
@XStreamAlias("faxphone")
private PhoneNumber fax;
// 测试一个标签下有多个同名标签
@XStreamAlias("friends")
private Friends friend;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public PhoneNumber getTel() {
return tel;
}
public void setTel(PhoneNumber tel) {
this.tel = tel;
}
public PhoneNumber getFax() {
return fax;
}
public void setFax(PhoneNumber fax) {
this.fax = fax;
}
public Friends getFriend() {
return friend;
}
public void setFriend(Friends friend) {
this.friend = friend;
}
}
关于实体代码需要说明:
XStream并不是根据注解再去找setter和getter的,所以这里的setter和getter方法完全没有必要。我这里有完全是因为测试代码中是通过setter和getter访问成员变量内容的原因。
其中PhoneNumber是对象类型:
@XStreamAlias("phoneNumber")
public class PhoneNumber {
@XStreamAlias("code")
private int code;
@XStreamAlias("number")
private String number;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
而Firends有集合类型的成员变量:
@XStreamAlias("friends")
public class Friends{
// itemFieldName定义重复字段的名称, 如果不加注解,默认为List中的类型,即string
@XStreamImplicit(itemFieldName="name")
private List<String> name;
public Friends(List<String> name) {
super();
this.name = name;
}
public List<String> getName() {
return name;
}
public void setName(List<String> name) {
this.name = name;
}
}
2.2 转换工具类
转换工具类代码如下:
public static String toXml(Object obj) {
// 指定编码解析器,直接用jaxp dom来解释
XStream xstream = new XStream(new DomDriver(XMLFILE_ENCODE));
// 通过注解方式的,一定要有这句话
xstream.processAnnotations(obj.getClass());
return xstream.toXML(obj);
}
2.3 测试代码
测试代码是这样的:
person = new SimplePerson();
person.setFirstName("张");
person.setLastName("三");
PhoneNumber tel = new PhoneNumber();
tel.setCode(137280);
tel.setNumber("137280968");
PhoneNumber fax = new PhoneNumber();
fax.setCode(20);
fax.setNumber("020221327");
person.setTel(tel);
person.setFax(fax);
// 测试一个标签下有多个同名标签
List<String> friendList = new ArrayList<String>();
friendList.add("A1");
friendList.add("A2");
friendList.add("A3");
Friends friends = new Friends(friendList);
person.setFriend(friends);
personXmlString = XmlUtil.toXml(person);
SimplePerson p = XmlUtil.fromXml(personXmlString, SimplePerson.class);
System.out.println(p);
3. 复杂类型的处理
比较复杂的类型我们可以看这个:
@XStreamAlias("complexPerson")
public class ComplexPerson {
@XStreamAlias("firstName")
private String firstName;
@XStreamAlias("lastName")
private String lastName;
@XStreamAsAttribute
@XStreamAlias("年龄")
private Integer age;
@XStreamAlias("birthday")
private Date birthday;
@XStreamAlias("telphone")
private PhoneNumber tel;
@XStreamAlias("faxphone")
private PhoneNumber fax;
// 测试一个标签下有多个同名标签
@XStreamAlias("friends")
private Friends friend;
@XStreamAlias("favoritePet")
private Pet favoritePet;
@XStreamAlias("pets")
private List<Pet> pets;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public PhoneNumber getTel() {
return tel;
}
public void setTel(PhoneNumber tel) {
this.tel = tel;
}
public PhoneNumber getFax() {
return fax;
}
public void setFax(PhoneNumber fax) {
this.fax = fax;
}
public Friends getFriend() {
return friend;
}
public void setFriend(Friends friend) {
this.friend = friend;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Pet getFavoritePet() {
return favoritePet;
}
public void setFavoritePet(Pet favoritePet) {
this.favoritePet = favoritePet;
}
public List<Pet> getPets() {
return pets;
}
public void setPets(List<Pet> pets) {
this.pets = pets;
}
}
以上的代码我们可以测试写入属性(attribute)值、集合等。
需要注意的是属性值的注解,先用@XStreamAsAttribute标识成员变量是一个属性,然后用@StreamAlias标识别名。
工具类和测试类基本不用改动,程序代码看起来非常整洁。
另外还有转换到XML文件、转换到JSON的代码,具体参见我写的例子:http://download.youkuaiyun.com/detail/cockroach/7188151