我的任务是重构一些使用 xmlbeans 的组件,以便现在使用 jaxb。一切都很顺利,直到我到达前一位作者调用XmlObjects 之一的 copy() 函数的地方。由于 xmlbeans 中的所有对象都扩展了 XmlObject,我们免费获得了神奇的深拷贝功能。
Jaxb 似乎没有为我们提供这个。制作 Jaxb 对象的深层副本的正确且简单的方法是什么?
我的任务是重构一些使用 xmlbeans 的组件,以便现在使用 jaxb。一切都很顺利,直到我到达前一位作者调用XmlObjects 之一的 copy() 函数的地方。由于 xmlbeans 中的所有对象都扩展了 XmlObject,我们免费获得了神奇的深拷贝功能。
Jaxb 似乎没有为我们提供这个。制作 Jaxb 对象的深层副本的正确且简单的方法是什么?
你可以参考这个
public static <T> T deepCopyJAXB(T object, Class<T> clazz) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
JAXBElement<T> contentObject = new JAXBElement<T>(new QName(clazz.getSimpleName()), clazz, object);
JAXBSource source = new JAXBSource(jaxbContext, contentObject);
return jaxbContext.createUnmarshaller().unmarshal(source, clazz).getValue();
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
public static <T> T deepCopyJAXB(T object) {
if(object==null) throw new RuntimeException("Can't guess at class");
return deepCopyJAXB(object, (Class<T>) object.getClass());
}
这个对我有用。
您可以使用 JAXBSource
假设您要深度复制 Foo 类型的 sourceObject。为同一类型创建 2 个 JAXBContext:
JAXBContext sourceJAXBContext = JAXBContext.newInstance("Foo.class");
JAXBContext targetJAXBContext = JAXBContext.newInstance("Foo.class");
然后做:
targetJAXBContext.createUnmarshaller().unmarshal(
new JAXBSource(sourceJAXBContext,sourceObject);
您可以使您的 JAXB 类可序列化,然后通过序列化和反序列化来深度复制对象。代码可能类似于:
Object obj = ... // object to copy
ObjectOutputStream out = new ObjectOutputStream(new ByteArrayOutputStream());
out.writeObject(obj);
byte[] bytes = baos.toByteArray();
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
Object copy = in.readObject();
您可以使用 XSD 中的注释为生成的 jaxb 对象声明基类...
<xsd:annotation>
<xsd:appinfo>
<jaxb:globalBindings>
<xjc:superClass name="com.foo.types.support.JaxbBase" />
</jaxb:globalBindings>
</xsd:appinfo>
</xsd:annotation>
您可以使用 xmlbeans 基类作为模板添加可克隆性支持。