XStream使用总结
最近做webService报文转换的公共接口使用到了XSream工具库,写个小总结备忘。。。
XStream是一个可以将javaBean与XML双向转换的java类库,本文内容基于xstream-1.4.4版本。所需maven依赖如下:
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.4</version>
</dependency>
1.基本使用方法
new Xstream().toXML(bean);
使用该方式转换的xml格式如下:
<org.xstream.test.People>
<age>10</age>
<name>sedric</name>
</org.xstream.test.People>
该格式由完整类名作为根节点,类成员变量名及变量值组成xml元素内容。
2.定义xml元素名、属性名别名
普通方式:
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格式如下:
<People Age__Alias="10" name="sedric"/>
注解方式:
@XStreamAlias("People")
public class People { @XStreamAlias("Age_Alias")
@XStreamAsAttribute
private int age; @XStreamAsAttribute
private String name;
使用注解方式时必须指定xstream解析annotations,方式如下:
//指定所有class均解析annotations
xstream.autodetectAnnotations(true);
//指定指定class解析annotations
xstream.processAnnotations(People.class);
3.xstream定义别名单下划线(_)双下划线(__)
xstream默认的转换方式中定义了对特殊字符的转换,代码如下:
//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:
//使用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相同层次的元素时,可以在该成员变量使用该注解。
@XStreamImplicit(itemFieldName = "List_Element")
private List<JP> jps;
转换的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。
@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如下:
<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注解属性:
//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属性。代码如下:
@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如下:
<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方法,只需注释该方法中如下内容:
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中存在子类属性时,转换将出现异常,不包含子类属性时,可转换成功。
相关:XStream实用指南
XStream使用总结的更多相关文章
- XStream将java对象转换为xml时,对象字段中的下划线“_”,转换后变成了两个的解决办法
在前几天的一个项目中,由于数据库字段的命名原因 其中有两项:一项叫做"市场价格"一项叫做"商店价格" 为了便于区分,遂分别将其命名为market ...
- XStream xml 解析框架使用笔记
1. xml的标签可以映射为类.类成员变量 2. 有子标签的标签映射为类,没有子标签的便签映射为类成员变量 3. 类名.类成员变量名如与标签名不一致需要通过注解或代码设置别名 // 类名 @XStre ...
- Xstream学习资料
java中有关xml操作的,我们项目中首推Xstream.至于原因不说了.跟着大众的脚步走应该没错的.有关Xstream的文档如下. 官方文档 XStream完美转换XML.JSON XStream实 ...
- XStream简单入门
简单的讲,XStream 涉及的就五个知识点:详情参考 官网 混叠,注解,转换器,对象流和操作json! 下面就用几个简单的例子来实现上述五个知识点! 基本步骤: 第1步:创建XStream对象. 通 ...
- 使用XStream解析MXL文件用到的jar包---xpp3_min-1.1.3.4.O.jar和xstream-1.3.1.jar
使用XStream解析MXL文件用到的jar包---xpp3_min-1.1.3.4.O.jar和xstream-1.3.1.jar
- Xstream解析XML
<oschina> <catalog>1</catalog> <newsCount>0</newsCount> <pagesize&g ...
- 打造完美的xml技术解决方案(dom4j/xstream)
转: XML 技术是随着 Java 的发展而发展起来的.在 XML 出现之前对于简单的数据格式通常是存储在 ini 配置文件等文本文件中,复杂的格式则采用自定义的文件格式,因此对于每种文件格式都要有专 ...
- XStream学习笔记
XStream 所需jar包: xstream-1.3.jar xpp3_min-1.1.4c.jar xmlpull-1.1.3.1.jar 目录: 1.注解去除,标签中带有包名的节点 2.注解修改 ...
- Java对象表示方式2:XStream实现对对象的XML化
上一篇文章讲到了使用Java原生的序列化的方式来表示一个对象.总结一下这种对象表示方式的优缺点: 1.纯粹的Java环境下这种方式可以很好地工作,因为它是Java自带的,也不需要第三方的Jar包的支持 ...
- XStream、JAXB 日期(Date)、数字(Number)格式化输出xml
XStream.Jaxb是java中用于对象xml序列化/反序列化 的经典开源项目,利用它们将对象转换成xml时,经常会遇到日期(Date).数字按指定格式输出的需求,下面是使用示例: 一.日期字段格 ...
随机推荐
- codeforces 580D:Kefa and Dishes
Description When Kefa came to the restaurant and sat at a table, the waiter immediately brought him ...
- jsp使用servlet实现验证码
在进行表单设计中,验证码的增加恰恰可以实现是否为“人为”操作,增加验证码可以防止网站数据库信息的冗杂等... 现在,小编将讲述通过servlet实现验证码: 验证码作为一个图片,在页面中为“画”出来的 ...
- 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication
题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...
- POJ 2976 Dropping tests(最大化平均值 or 01整数规划)
题目链接 忽略运算符逻辑导致奇怪的错误(代码中指明位置了) 输出没加0.5,WA. 还有,注意特殊情况k=0,所以scanf("%d%d", &n, &k)& ...
- iOS 关于本地持久化存储的探讨
目前,用以本地化存储的方式有很多,常用的有以下: 1.临时缓存 先说说临时缓存,临时缓存一般相当于用来管理应用程序中全局需要常用的一些内容.比如当前用户的ID或者当前的定位信息等. 常用的方式就是写一 ...
- Spring mvc web 配置
Spring Framework本身没有Web功能, Spring MVC使用WebApplicationContext类扩展ApplicationContext ,使得拥有web功能.那么,Spri ...
- 基本概率分布Basic Concept of Probability Distributions 6: Exponential Distribution
PDF version PDF & CDF The exponential probability density function (PDF) is $$f(x; \lambda) = \b ...
- AngularJs angular.equals
angular.equals 对比两个对象/值是否相等.支持值类型.正则表达式.数组和对象. 如果下列至少有一个是正确的,则将两个对象/值视为相等. 两个对象/值能通过===比较. 两个对象/值是同一 ...
- C语言:链表实现的一个实例
问题:写一个程序输入你一年看过的所有电影以及每部电影的各种信息(简化问题:每部电影只要求输入片名和评价) 链表实现: #include<stdio.h> #include<stdli ...
- 使用面向对象对XML进行解析:dom和dom4j的用法
这是一个比较简单的例子,主要是运用面向对象的思想,对XML文件进行解析,用dom和dom4j方法 <?xml version="1.0" encoding="utf ...