文档章节

XStream使用总结

上官无筵
 上官无筵
发布于 2013/07/18 23:23
字数 1230
阅读 6466
收藏 9

最近做webService报文转换的公共接口使用到了XSream工具库,写个小总结备忘。。。

    XStream是一个可以将javaBean与XML双向转换的java类库,本文内容基于xstream-1.4.4版本。所需maven依赖如下:

<!-- lang: xml -->
<dependency>
     <groupId>com.thoughtworks.xstream</groupId>
     <artifactId>xstream</artifactId>
     <version>1.4.4</version>
</dependency>

1.基本使用方法

    new Xstream().toXML(bean);

    使用该方式转换的xml格式如下:

<!-- lang: xml -->
<org.xstream.test.People>
    <age>10</age>
    <name>sedric</name>
 </org.xstream.test.People>

    该格式由完整类名作为根节点,类成员变量名及变量值组成xml元素内容。

2.定义xml元素名、属性名别名

普通方式:

<!-- lang: java -->
xstream.useAttributeFor(People.class,"age");
xstream.useAttributeFor(People.class,"name");
//定义Class别名
xstream.alias("People", People.class);
//定义Field别名
xstream.aliasField("Age_Alias", People.class, "age");

使用该方式转换的xml格式如下:

<!-- lang: xml -->
<People Age__Alias="10" name="sedric"/>

注解方式:

<!-- lang: java -->
@XStreamAlias("People")
public class People {

@XStreamAlias("Age_Alias")
@XStreamAsAttribute
private int age;

@XStreamAsAttribute
private String name;

使用注解方式时必须指定xstream解析annotations,方式如下:

<!-- lang: java -->
//指定所有class均解析annotations
xstream.autodetectAnnotations(true);
//指定指定class解析annotations
xstream.processAnnotations(People.class);

3.xstream定义别名单下划线(_)双下划线(__)

xstream默认的转换方式中定义了对特殊字符的转换,代码如下:

<!-- lang: java -->
//XmlFriendlyNameCoder.encodeName(String name)
for (; i < length; i++ ) {
            char c = name.charAt(i);
            if (c == '$' || c == '_' || c <= 27 || c >= 127) {
                break;
            }
 }

xstream对以上范围字符进行特殊字符转换,导致单下划线变为双下划线。解决方式:

    方法1:str.replaceAll("__","_");

    方法2:

<!-- lang: java -->
//使用xstream自带的NoNameCoder构造xstream,该方式将导致所有特殊字符都不转义
XStream xstream = new XStream(new XppDriver(new NoNameCoder()));
//使用Domdriver及NonameCoder构造xstream,该方式可以指定xml编码方式
XStream xstream = new XStream(new DomDriver("UTF-8", new NoNameCoder()));

    方法3:自定义NameCoder,对指定特殊字符进行转换。

4.XStreamImplicit注解使用

    当需要将collection或map类型的成员变量中数据转换成xml相同层次的元素时,可以在该成员变量使用该注解。

<!-- lang: java -->
@XStreamImplicit(itemFieldName = "List_Element")
private List<JP> jps;

转换的xml如下:

<!-- lang: xml -->
<People Age_Alias="10" name="sedric">
<List_Element>
<gender>man</gender>
<reason>人傻钱多</reason>
</List_Element>
<List_Element>
<gender>woman</gender>
<reason>巧言令色</reason>
</List_Element>
</People>

    XStreamImplicit注解有两个属性:itemFieldName是指当前集合数据转换为xml元素时的elementName;keyFieldName在集合元素为复杂对象时,会使用集合元素的成员变量名作为元素的elementName,当集合元素为基本数据类型及String类型时,keyFieldName指定的值将作为元素的elementName。

<!-- lang: java -->
@XStreamImplicit(itemFieldName = "String_Element", keyFieldName = "String_Field")
private List<String> stringList;

@XStreamImplicit(itemFieldName = "List_Element", keyFieldName = "List_Field")
private List<JP> jps;

@XStreamImplicit(itemFieldName = "Map_Element", keyFieldName = "Map_Field")
private Map<String, String> map;

转换的xml如下:

<!-- lang: xml -->
<People Age_Alias="10" name="sedric">
<String_Element>str1</String_Element>
<String_Element>str2</String_Element>
<List_Element>
<gender>man</gender>
<reason>人傻钱多</reason>
</List_Element>
<List_Element>
<gender>woman</gender>
<reason>巧言令色</reason>
</List_Element>
<Map_Element>value2</Map_Element>
<Map_Element>value1</Map_Element>
</People>

5.XStreamConverter注解使用

    xstreamConvert用于指定class及Field的converter(转换方式)。

    xstreamConvert定义于class时,该class及其所有成员变量(递归,即成员变量是复合对象时该符合对象的成员变量)均默认使用xstreamConvert指定的converter进行转换(满足converter.canConvert(Class type)时一定会使用指定的converter)。

    xstreamConvert定义与field时,该field如果是基本类型或String类型,满足canConvert(Class type)方法时使用该converter进行转换;如果是复合对象,则该对象所有成员变量(递归)满足canConvert(Class type)时使用该converter进行转换。

XStreamConverter注解属性:

<!-- lang: java -->
//priority指定converter优先级,即当有多个converter均可转换当前对象时,只使用priority
//最大的converter。
int priority() default XStream.PRIORITY_NORMAL;
//以下属性在指定值时,将会在构造该converter时作为构造方法的参数传入。
Class<?>[] types() default {};
String[] strings() default {};
byte[] bytes() default {};
char[] chars() default {};
short[] shorts() default {};
int[] ints() default {};
long[] longs() default {};
float[] floats() default {};
double[] doubles() default {};
boolean[] booleans() default {};

对于converter构造参数较复杂,上述属性不能满足构造参数时,可以使用xstream.registerConverter(参数。。)或xstream.registerLocalConverter(参数。。)来注册converter。

6.xstream对泛型、接口、超类的支持

对于复合类型对象,xstream默认使用ReflectionConverter来进行对象转换。该converter中定义了当属性定义类型与运行时类型不一致时,将会给该元素添加一个class属性。代码如下:

<!-- lang: java -->
@XStreamAlias("Generic")
public class GenericTypeTest {

@XStreamAlias("People")
private People people;

          GenericTypeTest generic = new GenericTypeTest();
           //SB是People的子类,SB中定义成员变量
 SB sb = new SB(50, "sb");

 generic.setPeople(sb);

转的xml如下:

<!-- lang: xml -->
<Generic>
<People class="org.xstream.test.SB" Age_Alias="50" name="sb">
<gender>woman</gender>
<reason>resson</reason>
</People>
</Generic>

当转换xml不需要该class属性时,可以通过自定义converter实现。实现方式参照AbstractReflectionConverter.doMarshal方法,只需注释该方法中如下内容:

<!-- lang: java -->
Class defaultType = mapper.defaultImplementationOf(fieldType);
if (!actualType.equals(defaultType)) {
String serializedClassName = mapper.serializedClass(actualType);
f (!serializedClassName.equals(mapper.serializedClass(defaultType))) {
// String attributeName =
// mapper.aliasForSystemAttribute("class");
// if (attributeName != null) {
// writer.addAttribute(attributeName,
// serializedClassName);
// }
}
}

对于xml转javabean,xstream默认的所有converter均不支持泛型、接口。如果存在超类时,xml中存在子类属性时,转换将出现异常,不包含子类属性时,可转换成功。

© 著作权归作者所有

上官无筵
粉丝 1
博文 9
码字总数 2454
作品 0
深圳
程序员
私信 提问
加载中

评论(3)

一只小桃子
一只小桃子
我改错位置了,5,搞了两个小时
一只小桃子
一只小桃子
XStream xstream = new XStream(new DomDriver("UTF-8", new NoNameCoder())); 我加了这个也没有用啊 操操操
陶俊OSCHINA
子类异常可以参考这个:http://www.natpryce.com/articles/000766.html
JavaBean到XML和JSON的转换

XML和JSON是当今常用的两种数据描述与传输的格式,特别是涉及到JS时使用JSON颇为频繁。自然,在Java的世界里少不了完成JavaBean与这两种格式相互转换的组件,那就是XStream和JSON-lib。这里我...

Idiot_s_Sky
2014/01/14
786
0
android下通过xstream解析xml格式信息

==========推荐============ 实例教程-----会员贡献索引贴 http://www.eoeandroid.com/thread-1987-1-1.html android 图像处理滤镜系列合集 http://www.eoeandroid.com/thread-178656-1-1.ht......

长平狐
2012/08/21
137
0
android下通过xstream解析xml格式信息

==========推荐============ 实例教程-----会员贡献索引贴 http://www.eoeandroid.com/thread-1987-1-1.html android 图像处理滤镜系列合集 http://www.eoeandroid.com/thread-178656-1-1.ht......

长平狐
2012/08/14
251
0
android下通过xstream解析xml格式信息

==========推荐============ 实例教程-----会员贡献索引贴 http://www.eoeandroid.com/thread-1987-1-1.html android 图像处理滤镜系列合集 http://www.eoeandroid.com/thread-178656-1-1.ht......

长平狐
2012/08/09
109
0
XStream转换时忽略未知字段

XStream是一个用于将对象序列化为xml以及将xml生成对象的库,通过它可以非常方便的做对象与xml(json等其他格式)之间的转换。但是在使用XStream过程中,会遇到xml元素与对象元素并不是一一匹配...

JasonSE
2014/04/29
10.3K
1

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周二乱弹 —— 他只能用这个办法劝你注意身体了

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @-冰冰棒- :#今日歌曲推荐# Kodaline《High Hopes》 《High Hopes》- Kodaline 手机党少年们想听歌,请使劲儿戳(这里) @xiaoshiyue :仙女...

小小编辑
10分钟前
399
10
Spring Boot Actuator 整合 Prometheus

简介 Spring Boot 自带监控功能 Actuator,可以帮助实现对程序内部运行情况监控,比如监控状况、Bean加载情况、环境变量、日志信息、线程信息等。这一节结合 Prometheus 、Grafana 来更加直观...

程序员果果
19分钟前
3
0
Linux文件查找命令详解

对于文件查找,我们最好用的还是属于find命令了,在说find命令之前,先把另外几个查找命令介绍一下。 目录 0x01 查询命令介绍 0x02 find命令介绍 0x01 查询命令介绍 在介绍之前,首先先了解一...

无心的梦呓
20分钟前
3
0
快速掌握的测试用例优先级划分方法

怎么样的设计才能算测试用例 引自:IEEE Standard 610 (1990): A set of test inputs, execution conditions, and expected results developed for a particular objective, such as to exe......

测者陈磊
23分钟前
3
0
[mycat]Attribute value "roadNodeId,version" of type NMTOKEN must be a name token

不能逗号配两个字段的主键 primaryKey="roadNodeId,version" Caused by: io.mycat.config.util.ConfigException: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 105; Attrib......

Danni3
29分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部