用XStream在JavaBean和XML之间进行转换

1、JavaBean和XML

      JavaBean和XML在工作中经常用到,而且有时候需要在两者之间进行转换。

      不想用Dom4j技术,于是使用了这个简单的包,XStream来进行JavaBena和XML之间的转换。

2、JavaBean   ---->  XML,基本转换

      先定义一个简单的JavaBean:

public class Person{
	private int age;
	private String name;
	List<String> girlFriends;
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public List<String> getGirlFriends() {
		return girlFriends;
	}
	public void setGirlFriends(List<String> girlFriends) {
		this.girlFriends = girlFriends;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}	
}
     在主程序中定义一个XStream对象,然后调用toXML方法即可:

public class TestXStream {
	public static void main(String[] args){
		XStream xstream = new XStream();
		Person person = new Person();
		person.setAge(17);
		person.setName("James");
		
		List<String> girlFriends = new ArrayList<String>();
		girlFriends.add("Lily");
		girlFriends.add("Baby");
		
		person.setGirlFriends(girlFriends);
		
		System.out.println(xstream.toXML(person));
	}
}
     输出结果如下:

<com.wxg.Person>
  <age>17</age>
  <name>James</name>
  <girlFriends>
    <string>Lily</string>
    <string>Baby</string>
  </girlFriends>
</com.wxg.Person>
    是不是<com.wxg.Person>看着非常碍眼,的确如此,我也觉得,所以XStream以注解的方式来解决这种问题

    将JavaBean改成如下的形式(注意黑体标明的注解):

<strong>@XStreamAlias("Person")</strong>
public class Person{
	private int age;
	private String name;
	List<String> girlFriends;
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public List<String> getGirlFriends() {
		return girlFriends;
	}
	public void setGirlFriends(List<String> girlFriends) {
		this.girlFriends = girlFriends;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}	
}
在主程序中需要添加一句autodetectAnnotations方法:

public class TestXStream {
	public static void main(String[] args){
		XStream xstream = new XStream();
		<strong>xstream.autodetectAnnotations(true);</strong>
		Person person = new Person();
		person.setAge(17);
		person.setName("James");
		
		List<String> girlFriends = new ArrayList<String>();
		girlFriends.add("Lily");
		girlFriends.add("Baby");
		
		person.setGirlFriends(girlFriends);
		
		System.out.println(xstream.toXML(person));
	}
}
3、如何处理属性,有时候我们想要如下的形式的xml:

<Person age="17">
  <name>James</name>
  <girlFriends>
    <string>Lily</string>
    <string>Baby</string>
  </girlFriends>
</Person>

其中age就是类Person的属性,其实属性和子节点使用起来并没有太大的区别,如果是简单类型的子节点,用属性来表示的话会比较好,看起来比较简洁。

为了得到上述形式的xml,我们需要在age属性处添加相应的注解:

@XStreamAlias("Person")
public class Person{
	@XStreamAsAttribute
	private int age;
	private String name;
	List<String> girlFriends;
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public List<String> getGirlFriends() {
		return girlFriends;
	}
	public void setGirlFriends(List<String> girlFriends) {
		this.girlFriends = girlFriends;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}	
}
此时,重新运行之前的程序,是不是得到你想要的结果了?

4、如果是如下的形式呢?

<Person age="17">James</Person>
在上述的XML结果中,我们剔除了成员变量List,age表示Person的属性,James表示的是Person的值,这时候应该怎样处理呢?

@XStreamAlias("Person")
<strong>@XStreamConverter(value=ToAttributedValueConverter.class, strings={"name"})</strong>
public class Person{
	@XStreamAsAttribute
	private int age;
	private String name;
	<strong>@XStreamOmitField</strong>
	List<String> girlFriends;
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public List<String> getGirlFriends() {
		return girlFriends;
	}
	public void setGirlFriends(List<String> girlFriends) {
		this.girlFriends = girlFriends;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}	
}
第一个注解表示的是将属性name转化成Person类的值,第二个注解表示在序列化成xml的时候忽略girlFriends这个属性。

目前用到的就是这些,不过XStream还是有缺陷的,其缺陷在于:

1. 反序列化的时候无法使用autodetectAnnotations()方法通知XStream对象去识别annotation。
还记的前面代码中xstream.autodetectAnnotations(true); 吗, 这句代码的意思是告诉XStream对象需要自动识别annotation, 这在序列化(JAVA bean-->XML)的时候没什么问题。但是在反序列化的时候就有问题了,原因官网上说的比较模糊,总之就是不行,只能通过xstream.processAnnotations(Class clazz) 来显式的注册需要使用annotation的类才行,如果JAVA bean很多就会比较麻烦。但一般来说JAVA bean在代码组织结构中都比较集中,如放在听一个package下,这样也好办,可以再程序中将该package下的JAVA bean都获取,然后使用xstream.processAnnotations(Class[] clazzs) 批量注册。
2. Null 属性无法被序列化。
之前举的例子JAVA bean中的属性都是被初始化以后才进行序列化的

目前用到的暂时就是这些,以后遇到再慢慢讨论。

你可能感兴趣的:(用XStream在JavaBean和XML之间进行转换)