Xstream:解组内部类

时间:2016-02-13 16:18:20

标签: java unmarshalling xstream

我想编组和解组其字段属于其类内部类的对象(如果我没有错,则为合成类)。

class A {
    private B field_b=null;
    public static class B {
        public static B B1 = new B("b1");
        public static B B2 = new B("b2");

        private final String name;
        private B(String name) {
            this.name=name;
            }
        }
    public B getBforName(String name) {
        if (B1.name.equals(name) return B1;            
        else if (B2.name.equals(name) return B2;
        else return null;            
    }

生成并读取XML:

<A>
    <field_B>b1</field_B>
</A>

写作部分很简单。

阅读部分比较复杂。

我想写一个转换器:

public class BConverter implements Converter {
    public boolean canConvert(Class type) {
        return B.class.isAssignableFrom(type) ;
    }
    public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
        // ...
    }
    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
        A parent_v1 = (A) context.getCurrentObject(); // !!! always empty
        A parent_v2 = (A) context.get("current_unmarshalled_A");

        return parent_v2.getBforName((String)reader.getValue());

    }
}

context.getCurrentObject()返回null并且似乎已过时(来自我阅读的论坛)。

context.get("current_unmarshalled_A")要求我输入unMarshallingContext,键和A对象被解组。没有写AConverter,我不会发现这样做。这不是很整洁,因为我会失去A类的默认解组行为。

有人有想法吗?

1 个答案:

答案 0 :(得分:0)

我不确定这是最干净的方式,但它有效。

我在B类中使用静态方法......

class A {
    private B field_b=null;
    public static class B {
        public static B B1 = new B("b1");
        public static B B2 = new B("b2");

        public static B getForName(String name) {
            if (B1.name.equals(name) return B1;            
            else if (B2.name.equals(name) return B2;
            else return null;            
        }

        private final String name;
        private B(String name) {
            this.name=name;
            }
    }

...和转换器中的反射

public class BConverter implements Converter {
    public boolean canConvert(Class type) {
        return B.class.isAssignableFrom(type) ;
    }
    public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
        writer.setValue(((B)source).getName())
    }
    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
        try {
            Method method = context.getRequiredType().getMethod("getForName", String.class);
            final String v = reader.getValue();
            Object b= method.invoke(null, v);
            if (b== null)
                throw new ConversionException("Could not retrieve a B object for \"" + v + "\"");
            return b;
        } catch (Exception ex) {
            throw new ConversionException("Error while retrieving a B object", ex);
        }
    }
}