XStream 与 JAXB 的使用对比

摘要

前几天在开发一个功能的时候,需要用到Java bean 和 xml 格式字符串之间的互转工具。
这边介绍两个工具,XStream 和 jdk 自带的 JAXB 系列工具类。

XStream

例如有如下的一个Java bean

Student s1 = new Student();
s1.setName("john");
s1.setAge(21);

使用XStream进行转换时,你将得到如下的xml字符串

<com.test.mytest.Student>
    <name>johnname>
    <age>21age>
com.test.mytest.Student>

也许你注意到了,XStream 在将java bean转化为xml格式的字符串时,根节点会默认转化为全路径。这显然不合理,我们生成xml格式字符串,作为报文传给对方系统,显然使用全路径是不合理的。然后XStream提供了别名功能,可以使用别名。这里有两种方式可以指定别名,一种是代码形式,一种是注解形式。推荐使用注解形式。

  1. 代码形式
XStream xstream = new XStream();  
// 将Student类使用类名作为别名
xstream.alias(Student.class.getSimpleName(), Student.class); 
Student student = new Student();  
student.setName("pli");  
student.setAge(18);  
String xmlStr = xstream.toXML(student);  
System.out.println(xmlStr);

序列化之后

<Student>
  <name>pliname>
  <age>18age>
Student>

也可以通过xstream.aliasField("NAME", String.class, "name");来指定字段别名

  1. 注解形式

Student类

@XStreamAlias("PERSON")  
public class Student {  
  
    @XStreamAlias("NAME")  
    private String name;  
    @XStreamAlias("AGE")  
    private int age;
}

主类方法

XStream xstream = new XStream();
// 设置自动处理全部注解,或处理指定注解,二选一即可
//xstream.autodetectAnnotations(true);  
xstream.processAnnotations(Student.class);  
Student student = new Student();  
student.setName("pli");  
student.setAge(18);  
String xmlStr = xstream.toXML(student);  
System.out.println(xmlStr);

序列化结果:

<PERSON>
  <NAME>pliNAME>
  <AGE>18AGE>
PERSON>
  1. 为什么推荐使用注解形式?
    我想你也注意到了,使用注解可以很方便的改变属性的名称格式。所以原因有如下
    Java bean 的属性命名格式为驼峰形式,而xml的节点命名为全大写。这种情况下,要想所有的属性都能和xml报文对上,使用注解无疑更加合理。
    例如:
XStream xstream = new XStream();  
xstream.alias(Student.class.getSimpleName().toUpperCase(), Student.class);  
  
String xmlStr2 = "\n" +  
                "  pli\n" +  
                "  18\n" +  
                "";  
Student student1 = (Student) xstream.fromXML(xmlStr2);  
System.out.println(student1.toString());

尽管指定了别名,但是对于大写的属性和类属性名称无法对应,执行报异常
XStream 与 JAXB 的使用对比_第1张图片

此时,如果使用注解,就可以轻松完成字段的映射。

JAXB

JAXB 其实就是注解版的 XStream,JAXB提供了自己的一套注解,通过注解来完成 Java bean 和 xml 节点之间的映射。

JAXBContext context = JAXBContext.newInstance(Teacher.class);  
Teacher teacher = new Teacher();  
teacher.setName("pli");  
teacher.setAge(18);  
Marshaller marshaller = context.createMarshaller();  
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);  
marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");  
StringWriter writer = new StringWriter();  
marshaller.marshal(teacher, writer);  
String jaxbStr = writer.toString();  
System.out.println(jaxbStr);  
  
Unmarshaller unmarshaller = context.createUnmarshaller();  
Teacher t1 = (Teacher) unmarshaller.unmarshal(new StringReader(jaxbStr));  
System.out.println(t1.toString());

输出结果如下:
XStream 与 JAXB 的使用对比_第2张图片

总结

  1. 推荐使用JAXB作为转换工具
  • 作为jdk原生的工具,JAXB 提供了更好的兼容性
  • XStream 在反序列化时,有代码注入风险(具体没有验证过)
  • JAXB 能自动添加和解析 xml 头部,省去了处理 xml 头部的功夫
  1. XStream 在使用时,一定要注意创建的实例。因为xstream的配置都是在实例上,如果重新创建了实例,那之前设置的属性都将失效。

你可能感兴趣的:(Java,java,xml,servlet)