【问题标题】:namespace issue on web service with Apache CXF使用 Apache CXF 的 Web 服务上的命名空间问题
【发布时间】:2013-05-13 14:20:55
【问题描述】:

我正在使用 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 &lt;{}id></faultstring>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

在我所做的所有研究中,这通常意味着命名空间在某处不匹配。但是我仔细检查了一遍,命名空间到处都是一样的,包括ObjectFactory.class、package-info.class、cxf-servlet.xml配置文件以及@WebService注解。谁能指出我在这里缺少什么的正确方向?

【问题讨论】:

  • 我终于找到了解决办法。当然那是在我把它贴在这里之后发生的,呃……由于我是新手,我的声誉太低,所以我要等到 8 小时前才能回答这个问题。然后我会发布我的解决方案。对不起,伙计们。
  • 为什么有人在没有解释或评论的情况下投了反对票?

标签: java web-services cxf jaxb2 java-ws


【解决方案1】:

问题的根源是wsgen,我认为这是一个bug。它不会使 wsdl 和 jaxb 生成的类兼容。在 jaxb 生成的类中,元素不是默认形式限定的,这会将参数元素放入 null 命名空间。但是在 WSDL 中,它IS 是默认形式限定的,这就是问题所在。可能有很多方法可以解决这个问题,我发现最快速和最肮脏的方法是在 @WebParam 注释上设置 targetNamespace。这里有代码 sn-ps 来演示我的意思,我希望这可以帮助遇到这个问题的其他人。

这是我最初为自下而上的实现类所做的:

@WebService(serviceName="OrderService")
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")
    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;

【讨论】:

  • 你做了什么来从&lt;faultcode&gt;值中删除soap:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-09
  • 2016-02-02
  • 1970-01-01
  • 1970-01-01
  • 2016-06-14
  • 2014-08-16
  • 1970-01-01
相关资源
最近更新 更多