Как сделать глубокую копию объекта JAXB, такого как xmlbean XmlObject.copy ()? - PullRequest
2 голосов
/ 18 мая 2009

Мне было поручено провести рефакторинг некоторых компонентов, которые теперь использовали xmlbeans для использования jaxb. Все идет отлично, пока я не доберусь до места, где предыдущий автор вызвал функцию copy () одного из XmlObjects . Поскольку все объекты в xmlbeans расширяют XmlObject, мы бесплатно получаем магическую функцию глубокого копирования.

Jaxb, кажется, не обеспечивает это для нас. Как правильно и просто сделать глубокую копию объекта Jaxb?

Ответы [ 4 ]

6 голосов
/ 03 июня 2015

Вы можете сослаться на это

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

Это работает для меня.

Весь кредит идет на https://gist.github.com/darrend/821410

3 голосов
/ 19 мая 2009

Вы можете объявить базовый класс для сгенерированных объектов jaxb, используя аннотацию в XSD ...

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

Вы можете добавить туда поддержку клонируемости, используя базовый класс xmlbeans в качестве шаблона.

3 голосов
/ 10 октября 2010

Вы можете использовать JAXBSource

Скажем, вы хотите глубоко скопировать sourceObject типа Foo. Создайте 2 JAXBContexts для того же Типа:

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

и затем сделайте:

targetJAXBContext.createUnmarshaller().unmarshal(
  new JAXBSource(sourceJAXBContext,sourceObject);
3 голосов
/ 19 мая 2009

Вы можете сделать ваши классы 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...