JAVA bean与XML互转的利器---XStream
来源:互联网 发布:wpsexcel数据分析工具 编辑:程序博客网 时间:2024/05/22 13:53
文章链接:http://www.tuicool.com/articles/im2IZn
最近在项目中遇到了JAVA bean 和XML互转的需求, 本来准备循规蹈矩使用dom4j忽然想起来之前曾接触过的XStream, 一番研究豁然开朗,利器啊利器, 下来就XStream的一些用法与大家分享。
XStream是大名鼎鼎的thought works下的一个开源项目, 主要功能是提供JAVA bean 和XML文本之间的转换,另外还提供JAVA bean和JSON之间的转换,这个不在本次讨论的范围内。
XStream进行转换是非常简单的,对JAVA bean没有任何要求:
- 不要求对private属性提供access方法(set/get)。
- 不要求提供默认构造函数。
实际的代码操作就更简单了,在JAVA1.5以后XSteam也支持了annotation。 这时就只要在JAVA BEAN中添加若干annotation就可以了,当然如果不允许修改JAVA bean, 那XStream也提供register的方式,也是很简单的。 我准备在例子中体现一下的topic:
- 基本转换
- 对象起别名
- 处理属性
- 处理List
- 忽略field
1. 基本转换
这是一个普通的JAVA bean:
package xstreamTest;public class Person {private String name;private int age;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void setName(String name) {this.name = name;}public String getName() {return this.name;}}
转换代码是这样的:
XStream xstream = new XStream();Person person = new Person();person.setName("pli");person.setAge(18);System.out.println(xstream.toXML(person));
我们得到了这样的结果:
<xstreamTest.Person> <name>pli</name> <age>18</age></xstreamTest.Person>
有没有觉得很奇怪为什么会有“xstreamTest.Person”的标签?对照下上面提到的JAVA bean这个标签是来自于JAVA bean的类全路径的。
可是这个并不是我想要的啊,有没办法改变?有,简单吗? 简单!
2. 起别名
家丁我们希望将“xstreamTest.Person” 这个莫名其妙的element标签改为“person”我们应该这么做。
package xstreamTest;@XStreamAlias("person")public class Person {private String name;private int age;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void setName(String name) {this.name = name;}public String getName() {return this.name;}}
而执行代码会变成这样:
XStream xstream = new XStream();xstream.autodetectAnnotations(true);Person person = new Person();person.setName("pli");person.setAge(18);System.out.println(xstream.toXML(person));
这样我们就得到了想要的:
<person> <name>pli</name> <age>18</age></person>
这里要提到的是“xstream.autodetectAnnotations(true);” 这句代码告诉XStream去解析JAVA bean中的annotation。这句代码有一个隐患,会在后面讨论。
别名可以改变任何你想在序列化时改变的对象名字,类,属性甚至包名,所用到的其实就是“XSstreamAlias”这个annotation。
3. 处理属性
如果想要将JAVA bean中的“age”属性作为XML中person标签的一个attribute该怎么办呢。
这里介绍另外一个annotation:@XStreamAsAttribute, 我们的JAVA bean变成了这样:
@XStreamAlias("person")public class Person {private String name;@XStreamAsAttributeprivate int age; public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void setName(String name) {this.name = name;}public String getName() {return this.name;}}
结果是这样的:
<person age="18"> <name>pli</name></person>
4. 处理List
如果JAVA bean中有List是什么情形呢。
@XStreamAlias("person")public class Person {private String name;@XStreamAsAttributeprivate int age;List<String> girlFriends; public List<String> getGirlFriends() {return girlFriends;}public void setGirlFriends(List<String> girlFriends) {this.girlFriends = girlFriends;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void setName(String name) {this.name = name;}public String getName() {return this.name;}}
直接转换我们会得到这样的结果:
<person age="18"> <name>pli</name> <girlFriends> <string>YuanYuanGao</string> <string>QiShu</string> <string>BoZhiZhang</string> </girlFriends></person>
结果其实也不赖,XStream在这里提供了一个@XStreamImplicit(itemFieldName=***)的annotation来满足用户想将List的根节点去掉和改变列表名字的需求,对应到我们的例子上就是去掉<girlFriends>标签和改变"<string>".我们来看看效果。
@XStreamAlias("person")public class Person {private String name;@XStreamAsAttributeprivate int age;@XStreamImplicit(itemFieldName="girl")List<String> girlFriends; public List<String> getGirlFriends() {return girlFriends;}public void setGirlFriends(List<String> girlFriends) {this.girlFriends = girlFriends;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void setName(String name) {this.name = name;}public String getName() {return this.name;}}
结果是这样:
<person age="18"> <name>pli</name> <girl>YuanYuanGao</girl> <girl>QiShu</girl> <girl>BoZhiZhang</girl></person>
5. 忽略属性
如果在JAVA bean中有些属性不想被序列化,XStream提供了解决这个需求的annotation: @XStreamOmitField
比如说不想讲girlfriends这个List序列化
@XStreamAlias("person")public class Person {private String name;@XStreamAsAttributeprivate int age;@XStreamImplicit(itemFieldName="girl")@XStreamOmitFieldList<String> girlFriends; public List<String> getGirlFriends() {return girlFriends;}public void setGirlFriends(List<String> girlFriends) {this.girlFriends = girlFriends;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void setName(String name) {this.name = name;}public String getName() {return this.name;}}
结果是这样:
<person age="18"> <name>pli</name></person>
6. Converter
Converter这个是属于XStream中的高级特性了,用于基本功能不能满足的情况下让客户自己定制序列化/反系列化的细节,我们还是通过一个例子进行说明。
假如我要往JAVA bean中添加一个类型为Date的属性:
@XStreamAlias("person")public class Person {private String name;@XStreamAsAttributeprivate int age;@XStreamImplicit(itemFieldName="girl")@XStreamOmitFieldList<String> girlFriends;Date birthday; public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public List<String> getGirlFriends() {return girlFriends;}public void setGirlFriends(List<String> girlFriends) {this.girlFriends = girlFriends;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void setName(String name) {this.name = name;}public String getName() {return this.name;}}
看看直接序列化的结果:
<person age="18"> <name>pli</name> <birthday>2012-08-04 04:35:01.857 UTC</birthday></person>
XStream的限制:
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中的属性都是被初始化以后才进行序列化的,如果没有初始化就进行序列化会怎样呢 ,还是举个例子
@XStreamAlias("person")public class Person {private String name = "pli";@XStreamAsAttributeprivate int age = 19;@XStreamImplicit(itemFieldName="girl")@XStreamOmitFieldList<String> girlFriends;@XStreamConverter(value=DateConverter.class)Date birthday = new Date(); public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public List<String> getGirlFriends() {return girlFriends;}public void setGirlFriends(List<String> girlFriends) {this.girlFriends = girlFriends;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void setName(String name) {this.name = name;}public String getName() {return this.name;}}
我想将其它属性都进行了初始化但是没有将girlFriends这个属性初始化,即使说girlFriends==null. 序列化以后会怎样呢?
<person age="18"> <name>pli</name> <birthday>2012-36-04</birthday></person>
girlFriends这个属性压根就没有被序列化,其实我是想让它序列化成这个样子:
<person age="18"> <name>pli</name> <birthday>2012-36-04</birthday> <girlFriends/></person>
有什么办法没,真没啥办法。我查了查源码,确实如果某个属性为null的话就不进行序列化的,唯一的办法是修改源码,这个太费事,如果你有兴趣请参看这个链接上的文章,会有帮助:点击打开链接
另外提一点,XStream也提供了不适用annotation的方式,有兴趣请在XStream的官网上查看。
点击打开链接 0 0
- JAVA bean与XML互转的利器---XStream
- JAVA bean与XML互转的利器---XStream
- JAVA bean与XML互转的利器---XStream
- JAVA bean与XML互转的利器---XStream
- JAVA bean与XML互转的利器---XStream
- JAVA bean与XML互转的利器---XStream
- Xstream XML文件互转JAVA对象的利器
- xstream : 实现XML 与 Java Object的互转
- XStream: Java对象和XML之间相互转换的利器
- xStream xml转java bean,抛出CannotResolveClassException异常原因
- XStream java xml 与 java对象互转
- xStream完美转换XML、JSON /XStream Xml与JavaBean对象的互转经典【转载】
- XML 处理利器 : XStream
- XML处理利器:XStream
- 使用XStream实现Java对象与XML之间的快速互转
- xStream 的简单使用 xml to bean
- XStream xml与javabean之间的互转
- Xml字符串和Java对象转换利器——XStream
- Android----微信支付
- maven 工程启动找不到 Spring ContextLoaderListener 的解决办法
- Android 系列 2.9设置首次运行首选项
- windows10 oracle 00119 和 00132终于搞定了,太不容易了!
- sched_clock为什么要retry
- JAVA bean与XML互转的利器---XStream
- R--SVM支持向量机
- RxBus
- PHP代码优化细节
- ssh上传下载文件
- 80老翁谈人生(321):CSDN政治违纪的事实证据
- J2EE进阶(二十)MyEclipse无法启动--Runtime Environment (JRE) or Java Development Kit (JDK) must be available
- PHP magic_quotes_gpc的详细使用方法
- liunx SSH密钥 免密码登录