【问题标题】:Xstream : unmarshalling inner classesXstream:解组内部类
【发布时间】:2016-02-13 16:18:20
【问题描述】:

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

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 类的默认解组行为。

有人有想法吗?

【问题讨论】:

    标签: java unmarshalling xstream


    【解决方案1】:

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

    我在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);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      • 2016-03-16
      • 1970-01-01
      相关资源
      最近更新 更多