Как использовать XmlAdapter для сопоставления сложных типов XML с объектами Java в классах, созданных схемой?

Используя эту (демонстрационную) схему, я создаю объекты Java с помощью JAXB:

<xsd:complexType name="someType">
    <xsd:sequence>
        <xsd:element name="myOtherType" type="otherType" maxOccurs="unbounded" />
    </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="otherType">
    <!-- ... -->
</xsd:complexType>

Этот класс генерируется:

@XmlType
public class SomeType {

    @XmlElement(name = "myOtherType")
    OtherType myOtherType;

}

Но я хотел бы использовать интерфейсы вместо реализаций в моих объектах, сгенерированных JAXB.

Поэтому я пишу этот интерфейс:

public interface OtherTypeInterface {
    // ....
}

И я позволил сгенерированному классу OtherType реализовать его с помощью файла привязки:

<jxb:bindings node="//xs:complexType[@name='otherType']">
    <inheritance:implements>com.example.OtherTypeInterface</inheritance:implements>
</jxb:bindings> 

Все идет нормально:

public class OtherType implements OtherTypeInterface {

    // ...

}

Но мне нужно, чтобы объект SomeType также использовал этот интерфейс вместо реализации OtherType. Как предложено в неофициальном руководстве по JAXB в разделе 3.2.2. Используйте @XmlJavaTypeAdapter, я хотел бы использовать самодельный XML-адаптер для сопоставления OtherType с его интерфейсом и наоборот:

public class HcpartyTypeAdapter extends XmlAdapter<OtherType, OtherTypeInterface> {

    @Override
    public OtherTypeInterface unmarshal(OtherType v) throws Exception {
        return v;
    }

    @Override
    public OtherType marshal(OtherTypeInterface v) throws Exception {
        return (OtherType) v;
    }

}

Но похоже, что сопоставление сложного типа XML в моем файле привязки со следующей конфигурацией — это большое нет-нет:

<jxb:globalBindings>
    <xjc:javaType name="com.example.OtherTypeInterface" xmlType="ex:otherType" adapter="com.example.OtherTypeAdapter"/>
</jxb:globalBindings>

Генерация завершается с ошибкой:

com.sun.istack.SAXParseException2; системный идентификатор: файл:/.../bindings.xjb; номер строки: 8; номер столбца: 22; неопределенный простой тип "{http://www.example.com}otherType".

С погуглив, я обнаружил, что невозможно использовать адаптеры XML для сложных типов в классах, сгенерированных схемой. Однако, если я вручную редактирую файлы для использования моего адаптера, он работает отлично:

public class SomeType {

    @XmlElement(name = "myOtherType")
    @XmlJavaTypeAdapter(OtherTypeAdapter.class)
    @XmlSchemaType(name = "otherType")   
    OtherTypeInterface myOtherType;

}

Я могу упорядочивать и разбирать его безупречно; но мне кажется, что редактирование сгенерированных классов сводит на нет всю цель автоматической обработки. Я имею дело с несколькими схемами, определяющими множество типов.

Итак, мой вопрос: кто-нибудь знает обходной путь для использования адаптеров XML для сопоставления сложных типов XML с объектами Java в классах, сгенерированных схемой, не прибегая к ручному редактированию кода?


Возможный ответ здесь: https://stackoverflow.com/a/1889584/946800. Я надеюсь, что с 2009 года кто-то, возможно, нашел способ решить эту проблему...


person Virginie    schedule 25.08.2016    source источник


Ответы (1)


вы можете использовать плагин jaxb2 annotate maven для добавления аннотаций к сгенерированным классам JAXB.

            <plugin>
                <!-- this plugin is used to add annotation for the models -->
                <groupId>org.jvnet.jaxb2_commons</groupId>
                <artifactId>jaxb2-basics-annotate</artifactId>
                <version>1.0.2</version>
            </plugin>

В привязках .xjb,

<jxb:bindings schemaLocation="sample.xsd">
    <jxb:bindings node="//xs:complexType[@name='otherType']">
        <annox:annotate target="field">
            <annox:annotate annox:class="@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter"
                value="com.example.OtherTypeAdapter.class" />
        </annox:annotate>
    </jxb:bindings>
</jxb:bindings>
person ulab    schedule 29.08.2016