- 浏览: 91497 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (148)
- 全文检索 (1)
- java (29)
- xml (2)
- json (2)
- redis springmvc (1)
- Redis (5)
- 开发常识 (1)
- tomcat (2)
- 单元测试Junit (2)
- 设计模式 (2)
- spring (10)
- jvm (2)
- eclipse (4)
- echart (1)
- mybatis (1)
- mysql (3)
- web (1)
- js (2)
- PL/SQL (2)
- 其他 (1)
- 人生 (1)
- 安全 (2)
- jsp (2)
- 硬件电脑 (1)
- linux (3)
- git (10)
- oracle (8)
- ant (1)
- maven (2)
- 正则表达式 (2)
- chrome (1)
- 面试 (6)
- 多线程 (19)
- bug (11)
- java工具类 (3)
- 算法 (1)
- bug,git (1)
- shell (2)
- springmvc (2)
- Java8 (1)
- 消息队列-rocketmq (1)
- es (1)
- dubbo (0)
- spring cloud (0)
- hashmap (0)
- springboot (1)
- velocity (0)
本文转自http://blog.csdn.net/pushme_pli/article/details/7829621
最近在项目中遇到了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:
转换代码是这样的:
我们得到了这样的结果:
有没有觉得很奇怪为什么会有“xstreamTest.Person”的标签?对照下上面提到的JAVA bean这个标签是来自于JAVA bean的类全路径的。
可是这个并不是我想要的啊,有没办法改变?有,简单吗? 简单!
2. 起别名
家丁我们希望将“xstreamTest.Person” 这个莫名其妙的element标签改为“person”我们应该这么做。
而执行代码会变成这样:
这里要提到的是“xstream.autodetectAnnotations(true);” 这句代码告诉XStream去解析JAVA bean中的annotation。这句代码有一个隐患,会在后面讨论。
别名可以改变任何你想在序列化时改变的对象名字,类,属性甚至包名,所用到的其实就是“XSstreamAlias”这个annotation。
3. 处理属性
如果想要将JAVA bean中的“age”属性作为XML中person标签的一个attribute该怎么办呢。
这里介绍另外一个annotation:@XStreamAsAttribute, 我们的JAVA bean变成了这样:
结果是这样的:
好玩吧。
4. 处理List
如果JAVA bean中有List是什么情形呢。
直接转换我们会得到这样的结果:
结果其实也不赖,XStream在这里提供了一个@XStreamImplicit(itemFieldName=***)的annotation来满足用户想将List的根节点去掉和改变列表名字的需求,对应到我们的例子上就是去掉<girlFriends>标签和改变"<string>".我们来看看效果。
结果是这样:
5. 忽略属性
如果在JAVA bean中有些属性不想被序列化,XStream提供了解决这个需求的annotation: @XStreamOmitField
比如说不想讲girlfriends这个List序列化
结果是这样:
6. Converter
Converter这个是属于XStream中的高级特性了,用于基本功能不能满足的情况下让客户自己定制序列化/反系列化的细节,我们还是通过一个例子进行说明。
假如我要往JAVA bean中添加一个类型为Date的属性:
看看直接序列化的结果:
还不错,但是生日只需要年月日就行了,没必要精确到毫秒,这怎么办呢,只能使用converter,我们这是就需要写代码了。
稍微解释下这段代码:DateConverter 实现了借口Converter,实现了接口中的三个方法:
•public boolean canConvert(Class clazz) 用来检测本converter是否能够转换输入的类型。
•public void marshal(Object object, HierarchicalStreamWriter writer,MarshallingContext context) 序列化的方法(JAVA bean --> XML)
•public Object unmarshal(HierarchicalStreamReader arg0, UnmarshallingContext arg1) 反序列化的方法。因为本例用不到所以没有实现。
此时我们的JAVA bean也要相应改变:
看看结果:
其实XStream转换过程就是执行一个个converter的过程,只不过使用的大部分converter都是内建好的,XStream遇到一个待转换的object首先去查找能够转换这个object的转换器(converter)怎么找呢,就是通过converter的canConvert(Class clazz)这个方法,返回为true就是可以转换。明白了吧。
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中的属性都是被初始化以后才进行序列化的,如果没有初始化就进行序列化会怎样呢 ,还是举个例子
我想将其它属性都进行了初始化但是没有将girlFriends这个属性初始化,即使说girlFriends==null. 序列化以后会怎样呢?
girlFriends这个属性压根就没有被序列化,其实我是想让它序列化成这个样子:
有什么办法没,真没啥办法。我查了查源码,确实如果某个属性为null的话就不进行序列化的,唯一的办法是修改源码,这个太费事,如果你有兴趣请参看这个链接上的文章,会有帮助:点击打开链接
另外提一点,XStream也提供了不适用annotation的方式,有兴趣请在XStream的官网上查看。
推荐其他网站的xstream转化xml的例子
http://www.blogjava.net/bolo/archive/2014/08/26/417353.html
http://lavasoft.blog.51cto.com/62575/64114/
http://www.cr173.com/html/11561_1.html
http://showlike.iteye.com/blog/1050843
http://hbiao68.iteye.com/blog/1958413
http://wenku.baidu.com/linkurl=4nZ95FWzTJiLRXf86U6tKA60BCcefCzE60SkmGFkBtjJDamLT21jcNOt7-_yIMfzsYK244eEwSoTCnfEysphv8HkD9DayN4TTWEpryGFeUm
最近在项目中遇到了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));
这里要提到的是“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; @XStreamAsAttribute 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; } }
结果是这样的:
<person age="18"> <name>pli</name> </person>
好玩吧。
4. 处理List
如果JAVA bean中有List是什么情形呢。
@XStreamAlias("person") public class Person { private String name; @XStreamAsAttribute private 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; @XStreamAsAttribute private 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; @XStreamAsAttribute private int age; @XStreamImplicit(itemFieldName="girl") @XStreamOmitField 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> </person>
6. Converter
Converter这个是属于XStream中的高级特性了,用于基本功能不能满足的情况下让客户自己定制序列化/反系列化的细节,我们还是通过一个例子进行说明。
假如我要往JAVA bean中添加一个类型为Date的属性:
@XStreamAlias("person") public class Person { private String name; @XStreamAsAttribute private int age; @XStreamImplicit(itemFieldName="girl") @XStreamOmitField List<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>
还不错,但是生日只需要年月日就行了,没必要精确到毫秒,这怎么办呢,只能使用converter,我们这是就需要写代码了。
public class DateConverter implements Converter { @Override public boolean canConvert(Class clazz) { return (Date.class).equals(clazz); } @Override public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) { Date date = (Date) object; Calendar calendar = Calendar.getInstance(); calendar.setTime(date); SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd"); writer.setValue(format.format(calendar.getTime())); } @Override public Object unmarshal(HierarchicalStreamReader arg0, UnmarshallingContext arg1) { return null; } }
稍微解释下这段代码:DateConverter 实现了借口Converter,实现了接口中的三个方法:
•public boolean canConvert(Class clazz) 用来检测本converter是否能够转换输入的类型。
•public void marshal(Object object, HierarchicalStreamWriter writer,MarshallingContext context) 序列化的方法(JAVA bean --> XML)
•public Object unmarshal(HierarchicalStreamReader arg0, UnmarshallingContext arg1) 反序列化的方法。因为本例用不到所以没有实现。
此时我们的JAVA bean也要相应改变:
@XStreamAlias("person") public class Person { private String name; @XStreamAsAttribute private int age; @XStreamImplicit(itemFieldName="girl") @XStreamOmitField List<String> girlFriends; @XStreamConverter(value=DateConverter.class) 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-50-04</birthday> </person>另外在这里简单说说converter的原理:
其实XStream转换过程就是执行一个个converter的过程,只不过使用的大部分converter都是内建好的,XStream遇到一个待转换的object首先去查找能够转换这个object的转换器(converter)怎么找呢,就是通过converter的canConvert(Class clazz)这个方法,返回为true就是可以转换。明白了吧。
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"; @XStreamAsAttribute private int age = 19; @XStreamImplicit(itemFieldName="girl") @XStreamOmitField List<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的官网上查看。
推荐其他网站的xstream转化xml的例子
http://www.blogjava.net/bolo/archive/2014/08/26/417353.html
http://lavasoft.blog.51cto.com/62575/64114/
http://www.cr173.com/html/11561_1.html
http://showlike.iteye.com/blog/1050843
http://hbiao68.iteye.com/blog/1958413
http://wenku.baidu.com/linkurl=4nZ95FWzTJiLRXf86U6tKA60BCcefCzE60SkmGFkBtjJDamLT21jcNOt7-_yIMfzsYK244eEwSoTCnfEysphv8HkD9DayN4TTWEpryGFeUm
相关推荐
XStream是一个开源库,它为Java对象提供了简单且直观的XML序列化和反序列化的解决方案。它不仅能够将Java对象转换成XML,反之亦然,还能支持JSON格式的转换。这个强大的工具在处理数据交换、持久化或配置文件时非常...
通过简单的API调用,开发者可以将复杂的Java对象结构转化为易于理解和处理的XML格式。 - **反序列化**: 反之,它也能将XML字符串解析回原来的Java对象。这使得XML数据能够被Java应用程序轻松地读取和操作。 2. **...
总之,Xstream 提供了一个强大且易于使用的工具,简化了 Java 对象与 XML 和 JSON 之间的转换。通过其丰富的 API 和注解支持,开发者可以灵活地定制序列化行为,满足各种需求。在实际开发中,Xstream 是处理 XML 和 ...
XStream库则是Java世界中一个强大的工具,它能够方便地实现XML和JSON与Java对象之间的互相转换。这篇博客文章,标题为“xStream学习xml,JASON,JAVA对象转换”,显然会探讨如何利用XStream来处理这两种数据格式。 ...
在Java开发中,数据序列化和反序列化是一项常见的任务,它允许我们将对象的状态转换为持久化的格式(如XML或JSON),以便存储或传输。XStream是一个强大的库,专门用于XML与Java对象之间的互相转换。这篇博文将深入...
xStream是一个强大的Java库,它能够轻松地将Java对象序列化为XML或反序列化为Java对象,同时也支持JSON格式。这篇学习笔记将深入探讨xStream的使用方法和特性,帮助你更好地理解和应用这个工具。 首先,xStream的...
xStream通过反射机制,将Java对象的字段与XML元素或JSON属性关联起来。这意味着,只需要简单的配置,xStream就能自动将一个对象转换为XML或JSON字符串,反之亦然。例如,一个名为`Person`的Java类可以被转换为如下的...
总之,xStream是一个功能强大且灵活的工具,能够方便地处理Java对象与XML和JSON之间的转换,极大地简化了数据序列化和反序列化的任务,尤其是在互联网应用中,对于数据交换和存储具有很高的实用价值。
XStream是一个用于XML、JSON和HTML的Java库,它能够将Java对象转化为XML,反之也能将XML数据还原为Java对象。在这个场景中,我们将深入探讨XStream如何处理日期类型,特别是使用`@XStreamConverter`注解来自定义Date...
- XStream的`fromXML()`方法可以将XML字符串直接转换为Java对象。 5. **性能和灵活性**: - JAXB是Java平台的标准,因此具有良好的性能和广泛的支持。然而,对于复杂的对象结构,配置可能较为繁琐。 - XStream...
xStream 是一个强大的 Java 库,它允许开发者轻松地在 Java 对象和 XML 或 JSON 文档之间进行序列化和反序列化。这个框架的核心优势在于其简单易用的API和高度自定义的能力,使得对象的表示能精确地映射到 XML 或 ...
这个示例可能包含了一个或多个演示如何使用 XStream 进行对象和 XML/JSON 之间转换的 Java 应用程序。这些示例可能包括创建对象、序列化为 XML/JSON、然后反序列化回对象的完整流程。通过运行提供的 jar 包,你可以...
Xstream是一个强大的Java库,它简化了对象与XML之间的序列化和反序列化过程。本文将深入探讨Xstream的特点和使用方法。 **Xstream的特点** 1. **灵活易用**:Xstream提供了简单易用的接口,用户无需深入底层细节就...
在Java中,我们可以通过DOM(文档对象模型)、SAX(简单API for XML)和JAXB(Java Architecture for XML Binding)等库来实现XML和对象之间的相互转换。下面我们将详细探讨这些方法。 1. DOM解析器: DOM是XML文档...
- **序列化**:将Java对象转化为XML字符串的过程。 - **反序列化**:将XML字符串转化为对应的Java对象。 2. **xStream的主要特点** - **易用性**:xStream通过简单的API设计,使得序列化和反序列化过程变得直观...
7. **支持JSON**:除了XML,XStream还支持JSON格式的数据交换,使得与JavaScript和Web服务的交互更为便捷。 在实际应用中,XStream广泛应用于数据持久化、网络传输、配置文件存储等场景。例如,在Web服务中,...
- 虽然这两个库主要用于JSON(JavaScript Object Notation)与Java对象的转换,但它们也有扩展支持XML。Jackson的`jackson-dataformat-xml`模块和Gson的`gson-to-xml`库可以实现XML与Java对象的互转。 7. XMLBeans...
xStream库就是一个这样的工具,它提供了一个简单易用的API,能够方便地将Java对象转化为XML或JSON格式,反之亦然。本文将深入探讨xStream 1.31版本的功能、使用方法以及其在处理XML和JSON数据时的优势。 首先,让...
XStream是一个功能丰富的库,提供了一种简洁的方式来处理Java对象和XML/JSON之间的转换。通过理解和掌握其核心特性、安全性设置以及自定义转换器,开发者可以在项目中充分利用XStream的优势,提高代码的可读性和可...
XStream 是一个强大的Java库,主要用于对象到XML以及XML到对象的序列化和反序列化。标题中的"xstream1.4.7bin"指的是XStream的1.4.7版本的二进制发行版,这通常包含了一系列的jar文件和其他运行时所需的资源,用于在...