2013-05-13 176 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