eip*_*ark 9 java import xstream
有没有办法创建转换器或在每次转换后执行的某些操作?对于上下文,我试图填充不在我的XML中的字段的默认值,以便在我的数据模型更改时保持向后兼容性.例如,如果我有这个对象:
class A {
private String b;
private String c;
private String d;
}
Run Code Online (Sandbox Code Playgroud)
我的XML是这样的:
<a>
<b>b</b>
<d>d</d>
</a>
Run Code Online (Sandbox Code Playgroud)
我希望我的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()我已经说过的不是有效的解决方案.
Ren*_*ink 10
XStream xstream = new XStream(new PureJavaReflectionProvider());
Run Code Online (Sandbox Code Playgroud)
并像往常一样使用默认值初始化您的对象.通过字段初始化或构造函数代码.
背景
如果您未指定ReflectionProviderxstream尝试查找最佳反射提供程序.但ReflectionProviderxstream的最佳选择对你来说可能不是最好的,因为它通常会选择Sun14ReflectionProvider.
在Sun14ReflectionProvider使用相同的实例化策略作为Java串行机制,这意味着,它跳过构造函数代码或更详细-对象初始化代码.
因此实例字段初始化如
class A {
private String b = "DEFAULT";
}
Run Code Online (Sandbox Code Playgroud)
将不会应用,也不会应用构造函数代码,例如
class A {
private String b;
public A(){
b = "DEFAULT";
}
}
Run Code Online (Sandbox Code Playgroud)
的PureJavaReflectionProvider,而不是使用(顾名思义)Java反射API来实例化对象,例如 Class.newInstance()和因此被执行初始化代码对象.
你需要一个转换器。
这是您的案例的代码示例:
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;
}
Run Code Online (Sandbox Code Playgroud)
}
不要忘记注册转换器:
XStream xs = new XStream();
xs.registerConverter(new AConverter());
Run Code Online (Sandbox Code Playgroud)
编辑:修复了转换器代码。