Используя эту (демонстрационную) схему, я создаю объекты 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 года кто-то, возможно, нашел способ решить эту проблему...