什么?
我正在使用CXF的wsdl2java从外部提供的wsdl(TravelItineraryReadRQ.wsdl
)生成Java类。
当我调用该操作时,我得到一个可以解组为Java类的响应,除了一个元素及其子元素(默认为DOM元素(ElementNSImpl
)
此元素有何特色?
相关元素(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
来独立解组JAXBContext
XML:
JAXBContext上下文= JAXBContext.newInstance(PQSPriceQuoteInfo.class)
在将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)
解组代码是什么样的?
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
wsdl生成的* PortType接口上的@XmlSeeAlso
批注包含ObjectFactory
类的列表。
通过复制和扩展TravelItineraryReadPortType
接口并将com.sabre.ns.ticketing.pqs.v1_0.ObjectFactory
添加到@XmlSeeAlso
批注中的列表中,我成功在解组PriceQuoteInfo元素的某些子元素期间触发了XML验证错误:>
unexpected element (uri:"http://www.sabre.com/ns/Ticketing/pqs/1.0", local:"ValidatingCarrier")
尽管不是很优雅,但它表明此方法试图解组PriceQuoteInfo
而不是将其保留为DOM对象,但是XML与我生成的GetPriceQuote
模式不完全匹配。我将关闭验证或找到匹配的架构来解决该问题。
问题
是否可以影响CXF / JAX-WS Web服务调用中使用的JAXBContext
,以便将ObjectFactory
的{{1}}添加到生成的* PortType中?
例如:是否有一种方法可以通过使用外部绑定来影响生成的@XmlSeeAlso批注,使其包含此ObjectFactory?
答案 0 :(得分:1)
有类似的问题。我发现没有直接影响JAXBContext
的方法,但是在创建JAX-WS代理时,我可以通过JaxWsProxyFactoryBean.setProperties()
注入ObjectFactory:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setProperties(
Collections.singletonMap(
"jaxb.additionalContextClasses",
new Class[{com.mypackage.ObjectFactory.class});
这样,我得到了JAXBElement<T>
而不是原始DOM对象(在您的情况下,T
将是PriceQuoteInfo
)。
希望有帮助。