2013-05-13 144 views
4

我正在使用Apache CXF 2.7.3,並且遇到名稱空間問題,我真的不明白。我已經嘗試過在這方面進行廣泛的搜索,但是我發現的大部分結果都是針對不同的行爲。問題是調用Web服務時,如果參數元素是名稱空間限定的,它將失敗。消息中的所有其他元素都是限定的,並且它只接受參數元素。這裏是精確的行爲:使用Apache CXF的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 &lt;{}id></faultstring> 
     </soap:Fault> 
    </soap:Body> 
</soap:Envelope> 

在所有我做過的研究,這通常意味着一個命名空間不匹配的地方。但我已經徹底檢查過了,命名空間在任何地方都是一樣的,包括ObjectFactory.class,package-info.class和cxf-servlet.xml配置文件以及@WebService註釋。任何人都可以指出我在正確的方向,我在這裏失去了什麼?

+0

我終於找到了解決方案。當然,這是在我發佈之後發生的,呃...因爲我是新人,而且我的名聲太低,所以在8個小時之前我不能回答這個問題。然後我會發布我的解決方案。抱歉的人。 – 2013-05-13 15:10:31

+0

爲什麼有人沒有解釋或評論downvote? – 2013-05-14 18:24:28

回答

8

問題的根源在於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類。正如你所看到的,它爲根設置了命名空間,但是它不是格式限定的,它也不會生成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; 
+2

你是如何從''值中刪除'soap:'的 – RaG 2014-05-18 11:24:44