JAVA bean与XML互转的利器---XStream
最近在项目中遇到了JAVA bean 和XML互转的需求, 本来准备循规蹈矩使用dom4j忽然想起来之前曾接触过的XStream, 一番研究豁然开朗,利器啊利器, 下来就XStream的一些用法与大家分享。
XStream是大名鼎鼎的thought works下的一个开源项目, 主要功能是提供JAVA bean 和XML文本之间的转换,另外还提供JAVA bean和JSON之间的转换,这个不在本次讨论的范围内。
XStream进行转换是非常简单的,对JAVA bean没有任何要求:
- 不要求对private属性提供access方法(set/get)。
- 不要求提供默认构造函数。
- 基本转换
- 对象起别名
- 处理属性
- 处理List
- 忽略field
- 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>
- 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>
- @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>
好玩吧。
- @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. 忽略属性
- @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>
- @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>
- 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;
- }
- }
- 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) 反序列化的方法。因为本例用不到所以没有实现。
- @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>
一个待转换的object首先去查找能够转换这个object的转换器(converter)怎么找呢,就是通过converter的
canConvert(Class clazz)这个方法,返回为true就是可以转换。明白了吧。
这句代码的意思是告诉XStream对象需要自动识别annotation, 这在序列化(JAVA
bean-->XML)的时候没什么问题。但是在反序列化的时候就有问题了,原因官网上说的比较模糊,总之就是不行,只能通过
xstream.processAnnotations(Class clazz) 来显式的注册需要使用annotation的类才行,如果JAVA
bean很多就会比较麻烦。但一般来说JAVA
bean在代码组织结构中都比较集中,如放在听一个package下,这样也好办,可以再程序中将该package下的JAVA
bean都获取,然后使用xstream.processAnnotations(Class[] clazzs) 批量注册。
- @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;
- }
- }
- <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>
转自 http://blog.csdn.net/pushme_pli/article/details/7829621
JAVA bean与XML互转的利器---XStream的更多相关文章
- JAVA Bean和XML之间的相互转换 - XStream简单入门
JAVA Bean和XML之间的相互转换 - XStream简单入门 背景介绍 XStream的简介 注解简介 应用实例 背景介绍 我们在工作中经常 遇到文件解析为数据或者数据转化为xml文件的情况, ...
- JAXB java类与xml互转
JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例文档反向 ...
- Java bean和json互转时,屏蔽某个属性
有的时候我们把java bean 转换成json的时候,希望屏蔽掉某个属性,这时可以在java bean的属性上加上@JsonIgnore注解,在com.fasterxml.jackson.annot ...
- java bean 转换工具
考量要素: 1.简单的约定优于配置的同名属性copy 2.嵌套属性copy 3.flattern(扁平化)支持,要支持N层结构的copy到一层结构. 4.性能 如下这个网页,里面提到了好多工具. ht ...
- 使用JAXB实现Bean与Xml相互转换
最近几天,我自己负责的应用这边引入了一个新的合作方,主要是我这边调用他们的接口,但是有个很坑的地方,他们传参居然不支持json格式,并且只支持xml格式进行交互,于是自己写了一个工具类去支持bean与 ...
- Java JSON、XML文件/字符串与Bean对象互转解析
前言 在做web或者其他项目中,JSON与XML格式的数据是大家经常会碰见的2种.在与各种平台做数据对接的时候,JSON与XML格式也是基本的数据传递格式,本文主要简单的介绍JSON/XML ...
- Spring基础篇——通过Java注解和XML配置装配bean
自动化装配的确有很大的便利性,但是却并不能适用在所有的应用场景,比如需要装配的组件类不是由自己的应用程序维护,而是引用了第三方的类库,这个时候自动装配便无法实现,Spring对此也提供了相应的解决方案 ...
- Java Jaxb JavaBean与XML互转
1.Jaxb - Java Arcitecture for XML Binding 是业界的一个标准,是一项能够依据XML Schema产生Java类的技术. Jaxb2.0是Jdk1.6的组成部分. ...
- Spring基础篇——通过Java注解和XML配置装配bean(转载)
作者:陈本布衣 出处:http://www.cnblogs.com/chenbenbuyi 本文版权归作者和博客园共有,欢迎转载分享,但必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留 ...
随机推荐
- 【转】Error: no `server' JVM at `C:\Program Files\Java\jre6\bin\server\jvm.dll'.解决办法
出现问题: 用java -jar XXX.jar -server -Xms900m -Xmx900m 或者 java -server -version 提示错误 Error: no `server' ...
- 再探Linux动态链接 -- 关于动态库的基础知识
在近一段时间里,由于多次参与相关专业软件Linux运行环境建设,深感有必要将这些知识理一理,供往后参考. 编译时和运行时 纵观程序编译整个过程,细分可分为编译(Compiling,指的是语言到平台 ...
- ###《More Effective C++》- 基础议题
More Effective C++ #@author: gr #@date: 2015-05-11 #@email: forgerui@gmail.com 一.仔细区别pointers和refere ...
- CStdioFile 写文件
前言: 介绍如何使用 CStdioFile 类去写文件. 完整工程代码,点我下载(请注意工程里面需要包含的 <locale.h>头文件 ) 示例: /// My Add // 获取当前路径 ...
- css3 animation实现逐帧动画
css3里面的animation属性非常强大,但是自己用的比较少,最近有次面试就刚好被问到了,趁现在有时间就对animation做一个小总结.同时实现一个逐帧动画的demo作为练习 animation ...
- PHP执行过程
PHP执行过程 任何一种语言的源代码计算机都没有办法直接执行,需要转换成计算机能够识别的机器指令. PHP也是一门高级语言,也需编译(解释) PHP的解析过程: 1.请求源代码,进行词法解析, ...
- struts2的java文件中不能直接弹出script对话框
需要引入接口 ServletResponseAware public class Login extends ActionSupport implements SessionAware,Servlet ...
- 三种读写XML的方法
XML文件是一种常用的文件格式,例如WinForm里面的app.config以及Web程序中的web.config文件,还有许多重要的场所都有它的身影.Xml是Internet环境中跨平台的,依赖于内 ...
- Cache的Add之委托解说
正文 想了想还是写了吧,虽然知识含量比较低..... 获取数据放到缓存中,自己用Add添加的结果老是报参数错误,我擦咧,自己还总感觉是委托的问题. call.Invoke(& ...
- Cassandra1.2文档学习(2)——节点间通信协议之gossip协议
参考文档:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/a ...