利用XStream在Java对象和XML之间相互转换

Xstream简介

Xstream是一种OXMapping 技术,是用来处理XML文件序列化的框架,在将JavaBean序列化,或将XML文件反序列化的时候,不需要其它辅助类和映射文件,使得XML序列化不再繁索。Xstream也可以将JavaBean序列化成Json或反序列化,使用非常方便。

主要使用

  • @XStreamAlias("student"): Java对象在xml中以标签的形式显示时,如果名字与类名或者属性名不一致,可以使用该标签并在括号内注明别名。等同于xstream.alias("student", Student.class)
  • @XStreamOmitField: 在输出XML的时候忽略该属性
  • @XStreamImplicit: 如果该属性是一个列表或者数组,在XML中不显示list或者Array字样。当需要将collection或map类型的成员变量中数据转换成xml相同层次的元素时,可以在该成员变量使用该注解,会将添加注释的节点去掉@XStreamImplicit(itemFieldName="studentList")
  • @XStreamAsAttribute: 该属性不单独显示成XML节点,而是作为属性显示出来。等同于xstream.useAttributeFor(Student.class, "sid")
  • @XStreamContainedType
  • @XStreamConverter: 设置转换器,用于指定class及Field的converter(转换方式)
  • @XStreamConverters: 主要用于将某些字段进行复杂的转换,转换过程写在一个类中

Xstream使用

(1)Maven依赖

1
2
3
4
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
</dependency>

(2)映射的xml代码

1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
<province province_code="ZJ">
<city id="1001" city_name="杭州" city_code="hanghzou" />
<city id="1002" city_name="宁波" city_code="ningbo" />
<city id="1003" city_name="温州" city_code="wenzhou" />
</province>

(3)在bean中加上相关注解

城市bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Data
@AllArgsConstructor
@NoArgsConstructor
@XStreamAlias("city")
public class City {
@XStreamAsAttribute
@XStreamAlias("id")
private String cityId;

@XStreamAsAttribute
@XStreamAlias("city_name")
private String cityName;

@XStreamAlias("city_code")
@XStreamAsAttribute
private String cityCode;
}

城市集合bean

1
2
3
4
5
6
7
8
@Data
@AllArgsConstructor
@NoArgsConstructor
@XStreamAlias("province")
public class CityList {
@XStreamImplicit(itemFieldName="city")
private List<City> cityList;
}

重命名注解:@XStreamAlias()
省略集合根节点:@XStreamImplicit
字段节点设置成属性:@XStreamAsAttribute
这些命名都需要和解析的xml的属性名一一对应,否则会报com.thoughtworks.xstream.mapper.CannotResolveClassException异常,找不到对应的类属性
集合属性需要使用:@XStreamImplicit,不然会报com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException转换器映射异常

(4)最后需要写个转换的工具类

1
2
3
4
5
6
7
8
9
10
public class XsteamUtil {
public static Object toBean(Class<?> clazz, String xml) {
Object xmlObject = null;
XStream xstream = new XStream();
xstream.processAnnotations(clazz);
xstream.autodetectAnnotations(true);
xmlObject= xstream.fromXML(xml);
return xmlObject;
}
}

Class<?> clazz指定我们需要转换的对象,xml是需要转的xml字符串

拓展了解

XStream提供了很多方法供我们使用

  • autodetectAnnotations(): 自动检测注解
  • processAnnotations(): 应用传递的类的注解
  • fromXML(): XML反序列化(JSON也是一样)
  • toXML(): XML序列化(JSON也是一样)
  • 自定义解析器

Xstream序列化XML,解析器用StaxDriver
指定解析器:XStream xstream = new XStream(new StaxDriver());

Xstream序列化Json,解析器用JettisonMappedXmlDriver
指定解析器:XStream xstream = new XStream(new JettisonMappedXmlDriver());

深入了解

XStreamxstream = new XStream();默认情况下,XStream会采用Xpp3库,XPP3是一种运行效率非常高的XML全解析实现。如果不想依靠Xpp3库的话,也可以使用一个标准的JAXP DOM解析器,可以采用以下语句进行初始化:

1
2
//不使用XPP3库
XStreamxstream = new XStream(new DomDriver());

此XStream实例,为线程安全的,可以供多个线程进行调用,共享使用。系统提供了多种标识解析器供我们选择,包括DomDriverJDomDriverStaxDriver等等。

XStream提供了对Json的支持,是因为Xstream内置了两个Driver:

  1. JsonHierarchicalStreamDriver:不依赖其他类库,只实现 obj->JSON
  2. JettisonMappedXmlDriver:依赖jettison类库,实现 JSON->obj or obj->JSON

两种Driver在处理相同设置的Object时会得到不同的JSON串,JsonHierarchicalStreamDriver得到的串更简洁,确如官网所说。JettisonMappedXmlDriver有个小问题,即默认输出带格式的JSON串,结构中带空格、换行,并且没有提供修饰方式。

总的来说,XStream使用起来更简便,代码跟简单,也容易理解,对于xml和Json都提供了支持,不需要其它辅助类和映射文件,使得XML,Json序列化不再繁琐。

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :