XStream介绍与使用

简介

  • XStream是Java类库,用来将对象序列化成XML (JSON)或反序列化为对象。XStream是自由软件,可以在BSD许可证的许可下分发。
  • XStream在运行时使用Java反射机制对要进行序列化的对象树的结构进行探索,并不需要对对象作出修改。XStream可以序列化内部字段,包括私private和final字段,并且支持非公开类以及内部类。
  • 在缺省情况下,XStream不需要配置映射关系,对象和字段将映射为同名XML元素。但是当对象和字段名与XML中的元素名不同时,XStream支持指定别名。XStream支持以方法调用的方式,或是Java 标注的方式指定别名。
  • XStream在进行数据类型转换时,使用系统缺省的类型转换器。同时,也支持用户自定义的类型转换器。

准备

pom依赖

<dependency>
	<groupId>com.thoughtworks.xstream</groupId>
	<artifactId>xstream</artifactId>
	<version>1.4.19</version>
</dependency>

普通实体类

public class Person {
    private int id;
    private String name;
    private int age;
    private List<String> hobbies;
    private List<Person> family;

    public Person(int id, String name, int age, List<String> hobbies, List<Person> family) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.hobbies = hobbies;
        this.family = family;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", age=" + age + ", hobbies=" + hobbies + ", family=" + family
                + "]";
    }
}

对象转XML

最简单转换

List<String> hobbies = new ArrayList<>();
hobbies.add("play");
hobbies.add("learn");

List<Person> list = new ArrayList<>();
Person brother = new Person(1, "哥哥", 22, hobbies, null);
Person sister = new Person(2, "妹妹", 17, null, null);
list.add(brother);
list.add(sister);

Person p = new Person(3, "小明", 20, hobbies, list);

XStream xs = new XStream();
String xml = xs.toXML(palias);
System.out.println(xml);

打印结果

<com.demo.test.Person>
  <id>3</id>
  <name>小明</name>
  <age>20</age>
  <hobbies>
    <string>play</string>
    <string>learn</string>
  </hobbies>
  <family>
    <com.demo.test.Person>
      <id>1</id>
      <name>哥哥</name>
      <age>22</age>
      <hobbies reference="../../../hobbies"/>
    </com.demo.test.Person>
    <com.demo.test.Person>
      <id>2</id>
      <name>妹妹</name>
      <age>17</age>
    </com.demo.test.Person>
  </family>
</com.demo.test.Person>

别名

  • 类别名 用 alias(String name, Class type) 方法
  • 类成员别名 用aliasField(String alias, Class definedIn, String fieldName)方法
  • 类成员作为属性别名 用useAttributeFor(Class definedIn, String fieldName)方法
...
XStream xs = new XStream();
xs.alias("person", Person.class);
xs.aliasField("code", Person.class, "id");
xs.useAttributeFor(Person.class, "id");
String xml = xs.toXML(p);
System.out.println(xml);

打印结果

<person code="3">
  <name>小明</name>
  <age>20</age>
  <hobbies>
    <string>play</string>
    <string>learn</string>
  </hobbies>
  <family>
    <person code="1">
      <name>哥哥</name>
      <age>22</age>
      <hobbies reference="../../../hobbies"/>
    </person>
    <person code="2">
      <name>妹妹</name>
      <age>17</age>
    </person>
  </family>
</person>

转换器

xml中hobbies元素标签使用 string元素标签表意不明,修改如下

 XStream xs = new XStream();
 xs.alias("person", Person.class);
 xs.aliasField("code", Person.class, "id");
 xs.useAttributeFor(Person.class, "id");
 ClassAliasingMapper classAliasingMapper = new ClassAliasingMapper(xs.getMapper());
 classAliasingMapper.addClassAlias("hobby", String.class);
 xs.registerLocalConverter(Person.class, "hobbies", new CollectionConverter(classAliasingMapper));
 String xml = xs.toXML(p);
 System.out.println(xml);

打印结果

<person code="3">
  <name>小明</name>
  <age>20</age>
  <hobbies>
    <hobby>play</hobby>
    <hobby>learn</hobby>
  </hobbies>
  <family>
    <person code="1">
      <name>哥哥</name>
      <age>22</age>
      <hobbies reference="../../../hobbies"/>
    </person>
    <person code="2">
      <name>妹妹</name>
      <age>17</age>
    </person>
  </family>
</person>

使用注解

  • 别名注解,使用注解 @XStreamAlias
  • 属性注解, @XStreamAsAttribute
  • 注解生效,使用autodetectAnnotations(boolean mode)方法

别名实体类

@XStreamAlias("person")
public class PersonAlias {
    @XStreamAlias("code")
    @XStreamAsAttribute
    private int id;
    @XStreamAlias("name")
    private String name;
    @XStreamAlias("age")
    private int age;
    @XStreamAlias("hobbies")
    private List<String> hobbies;
    @XStreamAlias("family")
    private List<PersonAlias> family;

    public PersonAlias(int id, String name, int age, List<String> hobbies, List<PersonAlias> family) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.hobbies = hobbies;
        this.family = family;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", age=" + age + ", hobbies=" + hobbies + ", family=" + family
                + "]";
    }
}
XStream xs = new XStream();
xs.autodetectAnnotations(true);
ClassAliasingMapper classAliasingMapper = new ClassAliasingMapper(xs.getMapper());
classAliasingMapper.addClassAlias("hobby", String.class);
xs.registerLocalConverter(PersonAlias.class, "hobbies", new CollectionConverter(classAliasingMapper));
String xml = xs.toXML(palias);
System.out.println(xml);

打印结果

<person code="3">
  <name>小明</name>
  <age>20</age>
  <hobbies>
    <hobby>play</hobby>
    <hobby>learn</hobby>
  </hobbies>
  <family>
    <person code="1">
      <name>哥哥</name>
      <age>22</age>
      <hobbies reference="../../../hobbies"/>
    </person>
    <person code="2">
      <name>妹妹</name>
      <age>17</age>
    </person>
  </family>
</person>

XML转对象

  • 需要别名设置
  • 需要转换器设置
  • 需要allowTypes ,解决com.thoughtworks.xstream.security.ForbiddenClassException问题
 String xml = "<person code=\"3\"><name>小明</name><age>20</age><hobbies><hobby>play</hobby><hobby>learn</hobby></hobbies><family><person code=\"1\"><name>哥哥</name><age>22</age><hobbies reference=\"../../../hobbies\"/></person><person code=\"2\"><name>妹妹</name><age>17</age></person></family></person>";
 XStream xs = new XStream();
 xs.alias("person", Person.class);
 xs.aliasField("code", Person.class, "id");
 xs.useAttributeFor(Person.class, "id");
 ClassAliasingMapper classAliasingMapper = new ClassAliasingMapper(xs.getMapper());
 classAliasingMapper.addClassAlias("hobby", String.class);
 xs.registerLocalConverter(Person.class, "hobbies", new CollectionConverter(classAliasingMapper));
 xs.allowTypes(new Class[] { Person.class });
 Person toPerson = (Person) xs.fromXML(xml);
 System.out.println(toPerson);

打印结果

Person [id=3, name=小明, age=20, hobbies=[play, learn], family=[Person [id=1, name=哥哥, age=22, hobbies=[play, learn], family=null], Person [id=2, name=妹妹, age=17, hobbies=null, family=null]]]

对象与JSON互转

引入JSON依赖

<dependency>
	<groupId>org.codehaus.jettison</groupId>
	<artifactId>jettison</artifactId>
	<version>1.4.1</version>
</dependency>
XStream xs = new XStream(new JettisonMappedXmlDriver());
xs.alias("person", Person.class);
xs.aliasField("code", Person.class, "id");
xs.useAttributeFor(Person.class, "id");
ClassAliasingMapper classAliasingMapper = new ClassAliasingMapper(xs.getMapper());
classAliasingMapper.addClassAlias("hobby", String.class);
xs.registerLocalConverter(Person.class, "hobbies", new CollectionConverter(classAliasingMapper));
String jsonStr = xs.toXML(p);
System.out.println(jsonStr);
xs.allowTypes(new Class[] { Person.class });
Person toPerson = (Person) xs.fromXML(jsonStr);
System.out.println(toPerson);

打印结果

{"person":{"@code":3,"name":"小明","age":20,"hobbies":[{"hobby":["play","learn"]}],"family":[{"person":[{"@code":1,"name":"哥哥","age":22,"hobbies":[{"@reference":"../../../hobbies"}]},{"@code":2,"name":"妹妹","age":17}]}]}}
Person [id=3, name=小明, age=20, hobbies=[play, learn], family=[Person [id=1, name=哥哥, age=22, hobbies=[play, learn], family=null], Person [id=2, name=妹妹, age=17, hobbies=null, family=null]]]

注意事项

  • 特殊符号
    处理下划线
    new XStream(new XppDriver(new XmlFriendlyNameCoder("-", "")))
    都不转义
    new XStream(new XppDriver(new NoNameCoder()))

  • XML转Java对象,元素标签不存在Java类中报错

class XStreamEx extends XStream {
    @Override
    protected MapperWrapper wrapMapper(MapperWrapper next) {
        return new MapperWrapper(next) {
            @Override
            public boolean shouldSerializeMember(@SuppressWarnings("rawtypes") Class definedIn, String fieldName) {
                if (definedIn == Object.class) {
                    return false;
                }
                return super.shouldSerializeMember(definedIn, fieldName);
            }
        };
    }
}

参考

百度百科XStream

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值