在XStream的领域不是在XML设置默认值(Set default value for field

2019-08-31 09:02发布

有没有一种方法来创建一个转换器或者是每一个转换后进行一些操作? 对于情况下,我想填充默认值不在我的XML,以保持向后如果我的数据模型更改兼容性领域。 举例来说,如果我有这个对象:

class A {
    private String b;
    private String c;
    private String d;
}

和我的XML是这样的:

<a>
 <b>b</b>
 <d>d</d>
</a>

我希望我的XML的进口知道有该字段的默认值c这是"c" ,并把它放在A如此。 这应该是一个通用的操作,我可以添加默认为一个非常复杂的图形的任何领域。 如果有一些方法来触发每次转换后的功能,它可以检查当前对象对地图,我想设置一个默认值的对象。

还要注意,使用的readResolve /的readObject似乎并没有是自1的readObject()似乎从来不为我所有和2的readResolve工作将覆盖使用默认值的字段,即使它实际上包含在XML选项。 请让我知道,如果我的假设这里是错的。

编辑::我发现用户邮件列表上此相关的主题: http://article.gmane.org/gmane.comp.java.xstream.user/4619/match=default+value

它似乎是唯一的建议解决方案是使用readResolve()我已经说的是不是一个有效的解决方案。

Answer 1:

使用PureJavaReflectionProvider

XStream xstream = new XStream(new PureJavaReflectionProvider());

和公正使用默认值照常初始化对象。 无论是通过场的初始化或构造函数代码(初始化)。

背景

如果不指定ReflectionProvider的XStream试图找到最好的反射提供商。 但是,最好的ReflectionProvider为XStream的未必是最适合你,因为它通常选择Sun14ReflectionProvider

所述Sun14ReflectionProvider使用相同的实例化策略作为Java串行机制,这意味着,它跳过构造函数代码或更精确-对象初始化代码。

因此实例字段初始化像

class A {
    private String b = "DEFAULT";
}

将不会被应用,也构造代码不会被应用,例如,

class A {
    private String b;

    public A(){
        b = "DEFAULT";
    }
}

所述PureJavaReflectionProvider而是使用(顾名思义)Java反射API来实例化对象,例如Class.newInstance()并因此执行初始化代码对象。



Answer 2:

你需要一个转换器。

这里是你的情况下,代码示例:

public class AConverter implements Converter {

    @Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    A a = new A();
    String bValue = "b";
    String cValue = "c";
    String dValue = "d";

    while (reader.hasMoreChildren()) {
        reader.moveDown();
        if ("b".equals(reader.getNodeName())) {
            bValue = reader.getValue();
        } else if ("c".equals(reader.getNodeName())) {
            cValue = reader.getValue();
        } else if ("d".equals(reader.getNodeName())) {
            dValue = reader.getValue();
        }
        reader.moveUp();
    }
    a.setB(bValue);
    a.setC(cValue);
    a.setD(dValue);

    return a;
}

@Override
public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) {
    A a = (A) object;
    writer.startNode("b");
    writer.setValue(a.getB());
    writer.endNode();
    writer.startNode("c");
    writer.setValue(a.getC());
    writer.endNode();
    writer.startNode("d");
    writer.setValue(a.getD());
    writer.endNode();


}

@Override
public boolean canConvert(Class clazz) {
    return clazz == A.class;
}

}

不要忘记注册的转换器:

XStream xs = new XStream();
xs.registerConverter(new AConverter());

编辑:固定的转换代码。



Answer 3:

c将被设置为null时,XML没有对设置的任何值c 。 然后,您可以检查null在您的getter和返回适当的默认值。



文章来源: Set default value for fields not in XML in XStream