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 本文版权归作者和博客园共有,欢迎转载分享,但必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留 ...
随机推荐
- Jsp与servlet之间页面跳转及参数传递实例(转)
原网址:http://blog.csdn.net/ssy_shandong/article/details/9328985 11. jsp与servlet之间页面跳转及参数传递实例 分类: Java ...
- nginx install in centos
1.在nginx下载rpm包,如nginx-release-centos-6-0.el6.ngx.noarch.rpm ,并安装(可用yum直接安装): 注:rpm包只是提供一个nginx源. 2.使 ...
- JavaScript学习笔记(8)——JavaScript语法之运算符
一. 算术运算符: 运算符 描述 例子 结果 + 加 x=y+2 x=7 - 减 x=y-2 x=3 * 乘 x=y*2 x=10 / 除 x=y/2 x=2.5 % 求余数 (保留整数) x=y%2 ...
- 关于main函数的定义
很多人甚至市面上的一些书籍,都使用了void main( ),其实这是错误的.C/C++中从来没有定义过void main( ).C++之父Bjarne Stroustrup在他的主页上的FAQ中明 ...
- java web-----MVC设计模式
一,MVC将代码分为三个部分,分别为视图(jsp),模型(javaBean),控制部分(servlet); 视图基本为 jsp 文件,主要内容为界面的html代码,负责显示界面: 模型为 javaBe ...
- 【nodemailer】 之邮件附件
nodemailer 续 之前对nodemailer做了一个简单的了解,这篇文章主要研究一下如何添加附加文件 测试代码 //Created by yyrdl on 2015/10/2. var nod ...
- OpenCV2学习笔记03:Qt中配置OpenCV环境
在Qt中开发基于OpenCV的应用时,需要配置对应函数库到环境变量,这时候我们需要使用到qmake能够识别的变量来指定环境变量. INCLUDEPATH: 用于指定搜索头文件到文件夹路径. LIBS: ...
- SQL技巧之分组求和
这是CSDN问答里面有人提出的一道问题,题目如下. 表格如下: 得出结果如下: 求精简的SQL语句. SQL查询语句: with a as( select rank() over (partition ...
- c#画正弦波
/// <summary> /// 画正弦曲线 /// </summary> /// <param name="sender"></par ...
- mysql存储过程讲解
1.数据库存储过程:简单滴说,存储过程就是存储在数据库中的一个程序. 2..数据库存储过程作用: 第一:存储过程因为SQL语句已经预编绎过了,因此运行的速度比较快. 第二:存储过程可以接受参数.输出参 ...