反序列化最终列表属性

时间:2012-11-19 16:52:39

标签: java xstream

假设我们有一个类测试,如:

public class Test {
    private final String name;
    private final List<String> list = new ArrayList<>();

    public Test(String name) {
        this.name = name;
    }

    void add(String s) {
        list.add(s);
    }

    void print() {
        System.out.println("name: " + name);
        for (String s : list) {
            System.out.println(" - " + s);
        }
    }
}

没有XSteam不变的

this.list != null

每次都持有。

但是,如果我们在

中进行第4次测试
public static void main(String[] args) {
    final XStream xstream = new XStream();
    xstream.alias("test", Test.class);

    // Serialize
    final Test test1 = new Test("XYZ");
    test1.add("One");
    test1.add("Two");

    //@formatter:off
    /* name: XYZ
     *  - One
     *  - Two
     */
    //@formatter:on
    test1.print();

    //@formatter:off
    /* <test>
     *   <name>XYZ</name>
     *   <list>
     *     <string>One</string>
     *     <string>Two</string>
     *   </list>
     * </test>
     */
    //@formatter:on
    System.out.println(xstream.toXML(test1));

    // Deserialize with one list entry
    final String xmlTest2 = "<test><name>XYZ</name><list><string>One</string></list></test>";
    final Test test2 = (Test) xstream.fromXML(xmlTest2);
    //@formatter:off
    /* <test>
     *   <name>XYZ</name>
     *   <list>
     *     <string>One</string>
     *   </list>
     * </test>
     */
    //@formatter:on
    test2.print();

    // Deserialize with empty list
    final String xmlTest3 = "<test><name>XYZ</name><list /></test>";
    final Test test3 = (Test) xstream.fromXML(xmlTest3);
    //@formatter:off
    /* name: XYZ
     */
    //@formatter:on
    test3.print();

    // Deserialize without list-tag
    final String xmlTest4 = "<test><name>XYZ</name></test>";
    final Test test4 = (Test) xstream.fromXML(xmlTest4);
    //@formatter:off
    /* name: XYZ
     * Exception in thead ... NullPointerException
     */
    //@formatter:on
    test4.print();
}

我们看到NullPointerException,因为list未初始化。

我希望XML中的list - 元素与test4类似。我能做什么?因为我的数据模型中有许多类与Test类似,所以我不想为每个类编写Converter。但是假设我会写一个Converter,我该如何设置最终属性name

1 个答案:

答案 0 :(得分:0)

请使用XStream Annotations and a custom Converter找到以下解决方案。

自定义转换器是以下类:

 public class ListableConverter implements Converter {

    public void marshal(Object source, HierarchicalStreamWriter writer,
            MarshallingContext context) {
        Listable listable = (Listable) source;
        writer.setValue(String.valueOf(... your marshalling logic here ...));
    }

    public Object unmarshal(HierarchicalStreamReader reader,
            UnmarshallingContext context) {
        List<String> list = new ArrayList<String>();
        // your unmarshalling logic here
        return list;
    }

    public boolean canConvert(Class type) {
        return type instanceof Listable;
    }
}

这是带有Annotations的修改过的Test类:

public class Test implements Listable{
    private final String name;

    @XStreamConverter(ListableConverter.class)
    private final List<String> list = new ArrayList<>();

    public List<String> getList() {
        return list;
    }

    public Test(String name) {
        this.name = name;
    }

    void add(String s) {
        list.add(s);
    }

    void print() {
        System.out.println("name: " + name);
        for (String s : list) {
            System.out.println(" - " + s);
        }
    }
}

最后,用于使转换器的接口适用于实现接口的模型中的任何类:

public interface Listable<String> {

    public List<String> getList();

}

因此,例如,模型中的另一个类可能如下所示:

    public class Foo implements Listable{

        @XStreamConverter(ListableConverter.class)
        private final List<String> anotherList = new ArrayList<>();

        ... omissis ...

        public List<String> getList() {
          return anotherList;
        }

   }