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中的属性都是被初始化以后才进行序列化的
目前用到的暂时就是这些,以后遇到再慢慢讨论。