Как расширить JAXBContext, используемый классами, сгенерированными CXF wsdl2java, чтобы включить дополнительный ObjectFactory - PullRequest
0 голосов
/ 20 февраля 2019

Что?

Я использую wsdl2java из CXF для генерации классов Java из внешнего wsdl (TravelItineraryReadRQ.wsdl).Когда я вызываю операцию, я получаю ответ, который могу разархивировать в классы Java, за исключением одного элемента и его дочерних элементов, которые по умолчанию имеют элементы DOM (ElementNSImpl)

Что особенного в этомelement?

Рассматриваемый элемент (PriceQuote) имеет тип (PriceQuoteType), определенный в схеме OpenReservation как xs:any:

<xsd:complexType name="PriceQuoteType">
  <xsd:choice>
      <xsd:any processContents="strict"/>
    </xsd:choice>
</xsd:complexType>

Почему это происходит?

Элемент, который я получаю (элемент PriceQuoteInfo), относится к пространству имен, на которое нет ссылок в этом wsdl, поэтому ни один из классов ObjectFactory, к которым относится JAXBContext был создан с, может демонтировать элемент.Поэтому он заканчивается как необработанные элементы DOM (ElementNSImpl).

Есть ли у меня схема, в которой определен тип PriceQuoteInfo?

Да, у меня естьполучил это и запустил на нем wsdl2java, чтобы сгенерировать для него Java-классы и добавить их к пути к классам.

Что я пробовал?

Чтобы включить PriceQuoteInfo для самостоятельного разбора, я создал внешний файл привязки для аннотирования PriceQuoteInfo как XmlRootElement и ссылался на этот файл в сборке maven:

<jaxb:bindings version="2.1"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:annox="http://annox.dev.java.net"
               jaxb:extensionBindingPrefixes="annox">    
    <jaxb:bindings schemaLocation="../PriceQuoteServices_v.3.0.0.xsd" node="/xsd:schema">
       <jaxb:bindings node="xsd:complexType[@name='PriceQuoteInfo.Get.Response']">
            <jaxb:class name="PQSPriceQuoteInfo"/>
            <annox:annotate target="class">
                <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="PriceQuoteInfo" namespace="http://www.sabre.com/ns/Ticketing/pqs/1.0"/>
            </annox:annotate>
        </jaxb:bindings>
    </jaxb:bindings>
  </jaxb:bindings>

Частичный успех

Затем я могу самостоятельно деархивировать PriceQuoteInfo XML, используя JAXBContext, инициализированный следующим образом:

JAXBContext context = JAXBContext.newInstance (PQSPriceQuoteInfo.class)

Когда unmarshalling PriceQuoteInfo как дочерний элемент элемента TravelItineraryReadRS, я также могу демонтировать его, объявив JAXBContext как:

  JAXBContext context = JAXBContext.newInstance(TravelItineraryReadRS.class, PQSPriceQuoteInfo.class)

или, альтернативно, используяих объектные фабрики:

  JAXBContext context = JAXBContext.newInstance(com.sabre.services.res.tir.v3_10.ObjectFactory.class, com.sabre.ns.ticketing.pqs.v1_0.ObjectFactory.class)

И как выглядит неустранимый кодe?

    InputStream inputStream = MyUnitTest.getResourceAsStream(filename)
    Unmarshaller unmarshaller = context.createUnmarshaller()
    JAXBElement<TravelItineraryReadRS> travelItineraryReadRS = unmarshaller.unmarshal(new StreamSource(inputStream), TravelItineraryReadRS.class)

И это выводит некоторые TravelItineraryReadRS XML в классы Java без каких-либо необработанных объектов DOM.

Так в чем же проблема?

Когда я вызываю эту службу через CXF / JAX-WS, PriceQuoteInfo демаршализирует в необработанные элементы DOM, поскольку я не нашел способа изменить JAXBContext, который используется для добавления фабрики отсутствующих объектов.

@ XmlSeeAlso

Аннотация @XmlSeeAlso в сгенерированном wsdl интерфейсе * PortType содержит список ObjectFactory классов.Реплицируя и расширяя интерфейс TravelItineraryReadPortType и добавляя com.sabre.ns.ticketing.pqs.v1_0.ObjectFactory в список в аннотации @XmlSeeAlso, мне удалось вызвать ошибку проверки XML во время демаршаллинга некоторых дочерних элементов элемента PriceQuoteInfo:

unexpected element (uri:"http://www.sabre.com/ns/Ticketing/pqs/1.0", local:"ValidatingCarrier")

Хотя и не очень элегантно, это показывает, что этот подход пытается демонтировать PriceQuoteInfo вместо того, чтобы оставить его как объекты DOM, но что XML не совсем соответствует сгенерированной мной схеме GetPriceQuote.Я либо отключу валидацию, либо найду подходящую схему для ее решения.

Вопрос

Можно ли повлиять на JAXBContext, используемый в CXF /Вызов веб-службы JAX-WS для добавления ObjectFactory для PriceQuoteInfo к сгенерированному * PortType?

Например: есть ли способ повлиять на сгенерированную аннотацию @XmlSeeAlso, чтобы она включала этот ObjectFactory, используя внешние привязки?

...