[英]namespace issue on web service with Apache CXF
我正在使用Apache CXF 2.7.3,並遇到一個我真的不明白的命名空間問題。 我已經嘗試過廣泛搜索,但我找到的大部分結果都是針對不同的行為。 問題是在調用Web服務時,如果參數元素是名稱空間限定的,它將失敗。 消息中的所有其他元素都是合格的,它接受它,而不是參數元素。 這是精確的行為:
請求WITHOUT參數元素限定:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ord="http://www.example.org/order">
<soapenv:Header/>
<soapenv:Body>
<ord:getOrder>
<id>a</id>
</ord:getOrder>
</soapenv:Body>
</soapenv:Envelope>
結果成功:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getOrderResponse xmlns:ns2="http://www.example.org/order">
<return>
<ns2:errorCode/>
<ns2:errorMessage/>
<ns2:order>
<ns2:orderNumber>ABC123</ns2:orderNumber>
<ns2:lastName>Smith</ns2:lastName>
</ns2:order>
</return>
</ns2:getOrderResponse>
</soap:Body>
</soap:Envelope>
請求WITH參數限定:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ord="http://www.example.org/order">
<soapenv:Header/>
<soapenv:Body>
<ord:getOrder>
<ord:id>a</ord:id>
</ord:getOrder>
</soapenv:Body>
</soapenv:Envelope>
導致JAXB異常:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Unmarshalling Error: unexpected element (uri:"http://www.example.org/order", local:"id"). Expected elements are <{}id></faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
在我所做的所有研究中,這通常意味着命名空間在某處不匹配。 但是我已經徹底檢查了它,並且命名空間在任何地方都是相同的,包括ObjectFactory.class,package-info.class和cxf-servlet.xml配置文件以及@WebService注釋。 任何人都可以指出我正確的方向,我在這里失蹤了什么?
問題的根源是wsgen,我認為這是一個錯誤。 它不會使wsdl和jaxb生成的類兼容。 在jaxb生成的類中,元素不是默認形式限定的,它將參數元素放入空命名空間。 但是在WSDL中,它是默認的表單限定,其中存在問題。 可能有很多方法可以解決這個問題,我發現最快速和最臟的方法是在@WebParam注釋上設置targetNamespace。 以下是用於演示我的意思的代碼片段,我希望這可以幫助遇到此問題的其他人。
以下是我最初為自下而上的實現類所做的事情:
@WebService(serviceName="OrderService")
public class OrderService {
public OrderResponse getOrder(@WebParam(name="id", targetNamespace="http://www.example.org/order") String id) {
這將導致以下生成的JAXB類。 正如您所看到的那樣,它為root設置了命名空間,但它不是形式限定的,並且它也不生成package-info文件。
@XmlRootElement(name = "getOrder", namespace = "http://www.example.org/order")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getOrder", namespace = "http://www.example.org/order")
public class GetOrder {
@XmlElement(name = "id")
private java.lang.String id;
然后我更改了服務實現類,將命名空間添加到@WebParam:
@WebService(serviceName="OrderService", targetNamespace="http://www.example.org/order")
public class OrderService {
public OrderResponse getOrder(@WebParam(name="id", targetNamespace="http://www.example.org/order") String id) {
雖然這不會使默認表單限定,但它會將命名空間添加到生成的JAXB類中的元素:
@XmlRootElement(name = "getOrder", namespace = "http://www.example.org/order")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getOrder", namespace = "http://www.example.org/order")
public class GetOrder {
@XmlElement(name = "id", namespace = "http://www.example.org/order")
private java.lang.String id;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.