Манипулирование объектами с использованием EclipseLink MOXy - PullRequest
0 голосов
/ 11 мая 2018

У меня есть два набора почти идентичных xsds для сотрудников, которые я использовал для генерации классов с помощью jaxb2-maven-plugin.
Эти два почти идентичны, за исключением одного для администратора, а другой для обычного пользователя.
1-й xsd xml выглядит так:

<Employee>
  <Head id="xxx" type="ADMIN"/>
  <Address type="HOME" from="dd-mm-yyyy">xxx</Address>
  <PayRate>34</PayRate>
</Employee>

2-й xsd xml выглядит так:

<Employee>
  <Head id="xxx" type="WORKER"/>
  <Address type="HOME">xxx</Address>
</Employee>

Как видите, нет тегов from (в адресном теге) и PayRate во втором xml.
У меня открыт API REST, где я всегда получаю 1-й отформатированный полезный груз. Но в зависимости от типа сотрудника. Мне нужно преобразовать его во 2-го с помощью Eclipse MOXy .

private static DynamicJAXBContext dynamicJAXBContext = DynamicJAXBContextFactory.createContextFromXSD(
    getClass().getClassLoader().getResourceAsStream("Employee-v1.xsd"), null, 
        com.something.Employee.class.getClassLoader(), null);

DynamicEntity dynamicEntity = (DynamicEntity) dynamicJAXBContext.createUnmarshaller().unmarshal(
    new ByteArrayInputStream(xmlMapper.writeValueAsString(employeePojoOfV2).getBytes(StandardCharsets.UTF_8)));

com.something.Employee emp = new com.something.Employee();

emp.sethead(JAXB.unmarshal(dynamicEntity.get("Head"), Head.class));
emp.setAddress(JAXB.unmarshal(dynamicEntity.get("Address"), Address.class));

Однако, всегда выдает следующую ошибку:

Exception [EclipseLink-25004] (Eclipse Persistence Services - 2.4.2.v20130514-5956486): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: An error occurred unmarshalling the document
Internal Exception: java.lang.ClassCastException: com.something.v2.Head cannot be cast to org.eclipse.persistence.internal.dynamic.DynamicEntityImpl

Это реально достижимо или я что-то не так делаю?

1 Ответ

0 голосов
/ 23 мая 2018
DynamicEntity dynamicEntity = (DynamicEntity) dynamicJAXBContext.createUnmarshaller().unmarshal(
    new ByteArrayInputStream(xmlMapper.writeValueAsString(employeePojoOfV2).getBytes(StandardCharsets.UTF_8)));

из приведенного выше кода вы обновляете с версии 1 xsd до объекта версии 2 с помощью unmarshal?

Предложение:

лучше вы можете использовать Xstream , чтобы легко выполнить Маршаллинг / Маршаллинг , когда вам нужно понизить рейтинг, просто используйте xstream.addImplicitCollectionфункция для определенных / любых полей, которые необходимо игнорировать, когда Marshalling переходит из объекта в xml.

Пример программы:

<customer>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <dob>1986-02-14 04:14:05.874 UTC</dob>
    <contactDetailsList>
        <ContactDetails>
            <mobile>6673543265</mobile>
            <landline>0124-2460311</landline>
        </ContactDetails>
        <ContactDetails>
            <mobile>4676543565</mobile>
            <landline>0120-223312</landline>
        </ContactDetails>
    </contactDetailsList>
</customer>

Давайте предположим, что нам нужно опустить родительские теги contactDetailsList, и мыпросто хочу, чтобы каждый элемент ContactDetails был дочерним по отношению к элементу customer.Давайте снова изменим наш пример:

xstream.addImplicitCollection(Customer.class, "contactDetailsList");

Вывод:

<customer>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <dob>1986-02-14 04:14:20.541 UTC</dob>
    <ContactDetails>
        <mobile>6673543265</mobile>
        <landline>0124-2460311</landline>
    </ContactDetails>
    <ContactDetails>`enter code here`
        <mobile>4676543565</mobile>
        <landline>0120-223312</landline>
    </ContactDetails>
</customer>
...