先附上XStream官方文档和API地址:
官方文档:http://x-stream.github.io/annotations-tutorial.html
API文档:http://x-stream.github.io/javadoc/
这种通过使用XStream的注解,来完成相关配置开发,必须要开启注解以保证注解生效,否则注解无效,默认注解是不生效的。
如下图,未开启注解序列化的XML如下,默认注解未生效:
开启注解检测的方式有两种,一种调用processAnnotations(),另一种调用autodetectAnnotations()。
两种方式区别在于
第一种方式:
调用processAnnotations,该方法有两种重载形式,如下图
参数可以传Class类对象,或者传Class类对象数组,这样你可以选择开启某一个类的注解或者开启某些类的注解。也就是仅认为某个类的注解有效或者某些类。
如下为参考代码:
public static String objToXML(Object xmlData) throws Exception{
String postDataXML;
try {
//指定解析编码为GBK,并解决XStream对出现双下划线的bug
XStream xStreamForReqData = new XStream(new DomDriver("GBK", new
XmlFriendlyNameCoder("-_", "_")));
//开启当前将被序列化为XML的类的注解
xStreamForReqData.processAnnotations(xmlData.getClass());
//将要提交给API的数据对象转换成XML格式数据Post给API
String postDataXMLOld = xStreamForReqData.toXML(xmlData);
postDataXML = postDataXMLOld.replace(""", "\"");
//为Bean转换后的XML加上头信息
postDataXML = XML_TAG + postDataXML;
} catch (Exception e) {
logger.error("Object converts into XML go wrong", e);
throw e;
}
return postDataXML;
}
第二种方式:
调用autodetectAnnotations() 如下图
该方法设置注解映射器的自动检测模式,true为开启。需注意,这种方式是在延迟加载模式下运行XStream,在这种模式下,它在处理对象时自动检测注解,并动态配置XStream实例。该方法相当于对使用到的所有实例XStream注解生效。
如下为参考代码:
static {
//指定解析编码为GBK,并解决XStream对出现双下划线的bug
xStreamForReqData = new XStream(new DomDriver("GBK", new XmlFriendlyNameCoder("-_",
"_")));
//开启注解(在类加载时调用一次,在后续每次调用序列化方法时会开启当前类的注解)
xStreamForReqData.autodetectAnnotations(true);
}
public static String objToXML(Object xmlData) throws Exception{
String postDataXML;
try {
//将要提交给API的数据对象转换成XML格式数据Post给API
String postDataXMLOld = xStreamForReqData.toXML(xmlData);
postDataXML = postDataXMLOld.replace(""", "\"");
//为Bean转换后的XML加上头信息
postDataXML = XML_TAG + postDataXML;
} catch (Exception e) {
logger.error("Object converts into XML go wrong", e);
throw e;
}
return postDataXML;
}
开启了注解后,这里为别名注解生效后的序列化结果:
注意:也正是基于这种懒加载的机制,所带来的问题,在官方文档中也有说明,一下为详细解释。
1、XStream实例缓存为注解处理的所有类类型。每次XStream转换一个对象时,它将在自动检测模式下首先处理对象的类型和所有相关的类型。因此,将对象序列化为XML是没有问题的,因为XStream已经加载了该类,扫描了注解,预先知道了其中的所有类型。
在反序列化时不再是这样。XStream必须知道别名才能将其转换为适当的类型,但是只有在预先处理了该类型之后,它才能找到别名的注释。因此,如果类型还没有反序列化,则反序列化将失败。这一点将在 ”XStream反序列化的坑“ 一文中详细分析。
2、XStream这种懒加载注解开启方式,定义了在处理对象时应用注解配置。因此,自动检测模式将把XStream的序列化过程变成一个线程不安全的操作。当XStream同步配置修改时,它不能保护并发读取,您可能在某些情况下遇到并发问题。也就是说在单例情况下processAnnotations这种方式已经在序列化前预加载了,所以即使多线程序列化,比如A线程该实例注解加载完了,准备序列化,此时B线程刚开始加载该实例注解,但不会影响A线程,因为已经加载到内存中了(加载过了),这种顶多是重复一遍的加载,但不会存在安全性问题。而autodetectAnnotations这种懒加载是在序列化过程中去加载,会存在多线程之间不同步问题,比如A线程序列化到第二个字段了,加载了别名注解"sex",但此时B线程刚开始序列化第一个字段可能加载的别名注解"name",这样可能就会导致A线程序列化字段名出错。
3、XStream使用定义良好的异常层次结构。如果是第一种预加载的方式,那么只有在序列化前,加载XStream注解时才会抛出InitializationException。如果注解是动态懒加载处理的,它们显然是在序列化过程中抛出。
4、因为预加载,所以不会影响序列化的性能。但懒加载因为是在序列化过程中去加载注解,所以可能会给整个序列化过程带来性能影响。