【问题标题】:Is it possible to remove wrapper element in WS result?是否可以删除 WS 结果中的包装器元素?
【发布时间】:2013-10-30 09:52:27
【问题描述】:

我的 CXF 项目运行良好。

我的WS界面是

package net.betlista.ws;

import javax.jws.WebMethod;
import javax.jws.WebService;

import org.apache.cxf.annotations.EndpointProperty;

@WebService
public interface TestWs {

    @WebMethod
    Result foo(String child);

}

实现是

package net.betlista.ws;

import org.springframework.stereotype.Component;

@Component("testWsEndpoint")
public class TestWsImpl implements TestWs {

    @Override
    public Result foo(final String child) {
        Result res = new Result();
        res.status = "ok";
        res.data = "bar";
        return res;
    }

}

结果类型类:

package net.betlista.ws;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

//@XmlTransient - NOT working
@XmlType
//@SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.BARE) - NOT working
public class Result {

    @XmlElement
    String status;

    @XmlElement
    String data;

}

当我通过请求调用 WS 时:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.betlista.net/">
   <soapenv:Header/>
   <soapenv:Body>
      <ws:foo>
         <arg0>a</arg0>
      </ws:foo>
   </soapenv:Body>
</soapenv:Envelope>

结果是:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns2:fooResponse xmlns:ns2="http://ws.betlista.net/">
         <return>
            <status>ok</status>
            <data>bar</data>
         </return>
      </ns2:fooResponse>
   </soap:Body>
</soap:Envelope>

我想跳过这个return 元素。

我想要:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns2:fooResponse xmlns:ns2="http://ws.betlista.net/">
        <status>ok</status>
        <data>bar</data>
      </ns2:fooResponse>
   </soap:Body>
</soap:Envelope>

我找到了this 的问题,但如果我使用它,元素arg 也会从请求中丢失什么是我不想要的。

我尝试将此@SOAPBinding 注释用于方法(如上所述)以及类型Result(不起作用)。

请求的 WSDL:

<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.betlista.net/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="TestWsImplService" targetNamespace="http://ws.betlista.net/">
  <wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.betlista.net/" elementFormDefault="unqualified" targetNamespace="http://ws.betlista.net/" version="1.0">
<xs:element name="foo" type="tns:foo"/>
<xs:element name="fooResponse" type="tns:fooResponse"/>
<xs:complexType name="foo">
    <xs:sequence>
      <xs:element minOccurs="0" name="arg0" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
<xs:complexType name="fooResponse">
    <xs:sequence>
      <xs:element minOccurs="0" name="return" type="tns:result"/>
    </xs:sequence>
  </xs:complexType>
<xs:complexType name="result">
    <xs:sequence>
      <xs:element minOccurs="0" name="status" type="xs:string"/>
      <xs:element minOccurs="0" name="data" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>
  </wsdl:types>
  <wsdl:message name="foo">
    <wsdl:part element="tns:foo" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="fooResponse">
    <wsdl:part element="tns:fooResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="TestWs">
    <wsdl:operation name="foo">
      <wsdl:input message="tns:foo" name="foo">
    </wsdl:input>
      <wsdl:output message="tns:fooResponse" name="fooResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="TestWsImplServiceSoapBinding" type="tns:TestWs">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="foo">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="foo">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="fooResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="TestWsImplService">
    <wsdl:port binding="tns:TestWsImplServiceSoapBinding" name="TestWsImplPort">
      <soap:address location="http://localhost:8080/tests-wicket-cxf/ws/TestWs"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

【问题讨论】:

  • 你能把wsdl放进去吗?
  • @AbhijithNagarajan:我认为 WSDL 无关紧要,但我添加了它。 WSDL 是从上面的类生成的...
  • @BetLista,WSDL 决定了soap 请求结构和响应结构。这是cxf的java2wsdl生成的wsdl的默认结构。您也可以根据需要对其进行自定义。
  • @BetLista,根据您的网络服务,假设返回 Result 类的对象,而 Result 是 w.r.t xsd 的非标准类。因此,如果您观察 wsdl,它会说,fooResponse 可能具有任何类型的元素 (xsd:anyType),并且只是将 Result 类的字段作为响应发送。 return 语句有什么问题?
  • 对不起,xsd:anyType 在那里,因为我正在尝试一些东西(它不起作用)。我知道我可以重命名元素...我添加了我想要实现的示例...由于技术原因存在结果标记 - java 方法最多具有一种返回类型...return 元素是(来自商业观点)毫无意义......

标签: java web-services jaxb cxf


【解决方案1】:

如果您想在 SOAP 请求中将 arg0 替换为 child,您应该在方法参数中添加 @WebParam(name="child") 注释。

您还可以通过使用@SOAPBinding(...) 注释服务(类)来影响生成的样式 - 使用哪种样式取决于您的需求/想法 - 请参阅我的第一条评论的链接以查看差异.

此外,请查看CXF docs 以查看每个@SOAPBinding 参数的默认值。

由于您想删除响应中的 return 元素,请注意这不符合 WS-I 标准,因为只允许使用一个 soap::body 孩子 - 但这是您的意图,您应该更改ParameterStyle.WRAPPED 默认 SOAPBinding 参数为 ParameterStyle.BARE。但是,这也可能会更改请求类型。也许看看@ResponseWrapper 这里。我还没用过,所以无法提供详细信息。

【讨论】:

  • 您能否详细说明“这不是 WS-I 兼容”部分?因为我不明白为什么我不能用它的定义替换对结果&lt;xs:element minOccurs="0" name="return" type="xs:anyType"/&gt; 的引用...请注意我更改了 WSDL,以前是错误的。
  • 我又读了一遍你的答案,soap:body 正好有一个元素 - fooResponse... 我想摆脱 return 元素...
【解决方案2】:

除了&lt;return&gt;tag,您可以通过在界面和实现中添加@javax.jws.WebResult(name = "result") 来使用自己的标签,例如&lt;result&gt;

@Override
@javax.jws.WebResult(name = "result")
public Result foo(final String child) {
    Result res = new Result();
    res.status = "ok";
    res.data = "bar";
    return res;
}

【讨论】:

    猜你喜欢
    • 2015-04-25
    • 2010-10-02
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多