How to make a deep copy of JAXB object like xmlbean XmlObject.copy()?

不打扰是莪最后的温柔 提交于 2020-01-15 06:49:47

问题


I have been tasked with refactoring some components that used xmlbeans to now make use of jaxb. Everything is going great, until I get to a place where the previous author has called the copy() function of one of the XmlObjects. Since all objects in xmlbeans extend XmlObject, we get the magic deep copy function for free.

Jaxb does not seem to provide this for us. What is the correct and simple way to make a deep copy of a Jaxb object?


回答1:


You could make your JAXB classes serializable and then deep copying an object by serializing and deserializing it. The code might look something like:

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();



回答2:


You can refer this

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());
}

It works for me.

All the credit goes to https://gist.github.com/darrend/821410




回答3:


You can use JAXBSource

Say you want to deep copy a sourceObject, of type Foo. Create 2 JAXBContexts for the same Type:

JAXBContext sourceJAXBContext = JAXBContext.newInstance("Foo.class");
JAXBContext targetJAXBContext = JAXBContext.newInstance("Foo.class");

and then do:

targetJAXBContext.createUnmarshaller().unmarshal(
  new JAXBSource(sourceJAXBContext,sourceObject);



回答4:


You can declare a base class for the generated jaxb objects using an annotation in the XSD...

<xsd:annotation>
  <xsd:appinfo>
    <jaxb:globalBindings>
      <xjc:superClass name="com.foo.types.support.JaxbBase" />
    </jaxb:globalBindings>
  </xsd:appinfo>
</xsd:annotation>

You can add the clonability support there using the xmlbeans base class as a template.



来源:https://stackoverflow.com/questions/879453/how-to-make-a-deep-copy-of-jaxb-object-like-xmlbean-xmlobject-copy

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!