Настройте имя объекта/элемента с помощью JAXB

Я очень новичок в JAXB, поэтому у меня возникли проблемы со взломом этого (я полагаю) очень простого варианта использования.

У меня есть набор схем, которые я получил. Я не контролирую их, я не могу их изменить. В этих схемах у меня есть такие объявления, как

<xs:complexType name="CustomerType">
    ...

Я пытаюсь создать классы из них. Таким образом, такое объявление становится

@XmlType(name = "CustomerType", propOrder = {
    "field1",
    "field2"
})
public class CustomerType {
    ...

Затем мне нужно использовать этот класс для создания XML-сообщений с помощью RestTemplate. Проблема в том, что объект в сообщении XML не должен быть «CustomerType», он должен быть просто «Customer». Как я уже сказал, я не могу редактировать схемы. Я также не могу напрямую редактировать сгенерированные источники. Мне нужна какая-то внешняя настройка, которая сообщает либо процессу генерации исходного кода, либо процессу сортировки, как преобразовывать имена объектов. Любой совет будет принят с благодарностью.


person Sethiel    schedule 19.04.2018    source источник


Ответы (2)


Вы можете использовать привязки для настройки имен классов или свойств. Обычно у вас будет такой файл, как bindings.xjb:

<jaxb:bindings version="1.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    jaxb:extensionBindingPrefixes="xjc">

    <jaxb:bindings schemaLocation="schema.xsd" node="/xsd:schema">
        <jaxb:bindings node="xsd:customType[@name='CustomerType']">
            <jaxb:class name="Customer"/>
        </jaxb:bindings>
        <jaxb:bindings node="xsd:customType[@name='CustomerType']//xsd:element[@name='field1']">
            <jaxb:property name="f1"/>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

С помощью привязок можно настроить довольно много вещей (см. это), но, конечно, не все.

person lexicore    schedule 19.04.2018
comment
Спасибо. Я не вижу способа настроить имя корневого объекта с помощью внешнего файла привязки (не только класса, но и имени, которое будет использоваться для смешивания, которое находится в аннотации @XmlType атрибута имени). - person Sethiel; 19.04.2018
comment
Вы уверены, что для этого нужно изменить @XmlType? Это выполнимо, но я сомневаюсь, что Джексон действительно принимает @XmlType. - person lexicore; 19.04.2018
comment
Я неправильно выразился. Я имел в виду, что мне нужно изменить значение, определенное в @XmlType. На самом деле я не могу изменить саму аннотацию, потому что она находится в сгенерированном источнике. Вот почему я ищу способ сделать это каким-то образом с помощью внешнего файла. - person Sethiel; 20.04.2018
comment
@Sethiel Ну, возможно, вы неправильно сформулировали это, но теперь оно сформулировано так, как оно сформулировано, и это ответ. - person lexicore; 20.04.2018
comment
@Sethiel Я могу показать вам, как изменить @XmlType с помощью jaxb2-annotate-plugin, но сначала давайте сделаем этот вопрос. Примите ответ, задайте другой вопрос. - person lexicore; 20.04.2018
comment
@Sethiel В новом вопросе предоставьте минимальный, полный, поддающийся проверке пример. Я серьезно сомневаюсь, что @XmlType влияет на сортировку Джексона, поэтому вы вполне можете решать проблему XY< /а>. Вот почему здесь необходим MCVE. Возможно, вам вообще не нужно изменять @XmlType. - person lexicore; 20.04.2018

Способ создания объектов DTO:

Вы определяете все типы в одном месте, такие как: CustomerType, UserType, OrderType и так далее.

Затем вы создаете другую схему и импортируете соответствующие XSD, в которых вы определили несколько типов. Затем вы фактически используете/агрегируете эти определения типов для создания XML-схемы для объектов. Что-то вроде ниже

<xs:complexType name="CustomerOrders">
<xs:element name="Customer" type="CustomerType">
<xs:attribute name="Orders" type="OrderType">
person piy26    schedule 19.04.2018
comment
Я не понимаю, что вы предлагаете. Кроме того, у меня есть ровно один файл xsd для запроса и один файл для ответа для каждой службы. - person Sethiel; 19.04.2018
comment
У вас должен быть другой сложный тип оболочки, который упаковывает объект CustomerType. Как вы упомянули, у вас есть XSD для каждого объекта запроса и ответа, тогда ваш объект запроса должен иметь элемент xs:, который имеет тип CustomerType. Можете ли вы поделиться своим запросом XSD? - person piy26; 19.04.2018
comment
Я не думаю, что могу поделиться XSD. Но да, у меня есть еще одна оболочка complexType. Что-то вроде <xs:complexType name="individualType"> <xs:sequence> <xs:element name="individual-name" type="individual-nameType"/> <xs:element name="date-of-birth" type="xs:string"/> </xs:sequence> </xs:complexType> Это в том же файле, который я не могу редактировать. Теперь мне нужно, чтобы эти объекты были переведены в индивидуальные и индивидуальные имена. Что именно ты предлагаешь мне сделать? - person Sethiel; 19.04.2018
comment
Как видно здесь, индивидуальное имя и дата рождения являются дочерними элементами объекта IndividualType и, следовательно, могут использоваться путем получения экземпляра объекта IndividualType. Вам нужно выполнить поиск XSD, чтобы найти какой-либо комплексный тип, который обертывает индивидуальный тип. - person piy26; 19.04.2018
comment
Хорошо, оказывается, я был настолько невежественен, что задал неправильный вопрос. Итак, позвольте мне задать вопрос с самого начала: как я могу изменить имя root complexType, к которому будет маршалироваться, не изменяя схему и не добавляя никаких аннотаций к сгенерированному коду? - person Sethiel; 19.04.2018
comment
Вы не можете этого сделать, поскольку все строго регулируется определением XSD, и в этом вся суть XSD. Представьте, что кто-то на другой стороне получает упорядоченный XML (с вашими измененными именами), но использует тот же XSD, что и ваш. Эта сторона будет совершенно невежественна. - person piy26; 19.04.2018
comment
@piy26 Вы не можете этого сделать - это неправильно. Сгенерированный код можно в значительной степени настроить с помощью привязок. - person lexicore; 19.04.2018