如何在 JAX-WS 客户端中指定 ReplyTo EndpointReference?

Posted

技术标签:

【中文标题】如何在 JAX-WS 客户端中指定 ReplyTo EndpointReference?【英文标题】:How to specify ReplyTo EndpointReference in a JAX-WS client? 【发布时间】:2012-06-04 12:10:30 【问题描述】:

我想使用 JAX-WS API 创建启用 WS-Addressing 的 Web 服务客户端。我使用 wsimport 从 WSDL 文件创建客户端存根,并且可以使用 AddressingFeature 启用/禁用 WS-Addressing,例如

Hello hello = service.getHelloSoap11(new AddressingFeature(true, true));

但是,我在 Web 中找不到任何自定义 WS-Addressing ReplyTo/FaultTo 端点引用的示例。基本上我想创建一个如下所示的 WS 请求(参见 wsa:ReplyTo 元素):

<soapenv:Envelope ...>
  <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <wsa:To soapenv:mustUnderstand="1">http://localhost:8080/poc/helloService/
    </wsa:To>
    <wsa:ReplyTo>
      <wsa:Address>http://mycompany.com/poc/reply</wsa:Address>
      <wsa:ReferenceParameters>
        <field1 xmlns="http://mycompany.com/poc/cust">some value1</field1>
        <field2 xmlns="http://mycompany.com/poc/cust">some value2</field2>
      </wsa:ReferenceParameters>
    </wsa:ReplyTo>
    <wsa:Action>http://mycompany.com/poc/sayHello</wsa:Action>
    <wsa:MessageID>urn:uuid:7849b04f-c74e-4836-99e4-8e25d2700fae
    </wsa:MessageID>
  </soapenv:Header>
  <soapenv:Body>
    ...
  </soapenv:Body>
</soapenv:Envelope>

如果使用 Spring Web Service 客户端,我可以添加端点引用。但是,我需要使用 JAX-WS 来完成。有什么想法吗?

【问题讨论】:

【参考方案1】:

我回答我自己的问题。

似乎标准的 JAX-WS API 没有提供一种方便的方法来自定义 WS-Addressing From/ReplyTo/FaultTo 端点引用。但是,每个 JAX-WS 运行时都可能提供额外的专有 API 来设置标头。

例如,IBM JAX-WS RI 提供 EndpointReferenceManager SPI 来创建端点引用:

    import com.ibm.wsspi.wsaddressing.EndpointReference;
    import com.ibm.wsspi.wsaddressing.EndpointReferenceManager;
    import com.ibm.wsspi.wsaddressing.WSAConstants;

    public void testWSAddressing () 

    // get the port
    Hello hello = service.getHelloSoap11();

    // build a EndpiontReference of <wsa:ReplyTo>
    BindingProvider bp = (BindingProvider) hello;
    EndpointReference epr = EndpointReferenceManager.createEndpointReference(new URI(
       "http://www.w3.org/2005/08/addressing/anonymous"));
    epr.setReferenceParameter(new QName("http://mycompany.com/test", "someRefParam"),
                "12345678");

    ((BindingProvider) hello).getRequestContext()
            .put(WSAConstants.WSADDRESSING_REPLYTO_EPR, epr);
    ...

    HelloResponse response = hello.hello(request);
    

上述代码在 IBM Websphere 中运行时,将生成如下所示的 SOAP 消息:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <wsa:To>http://localhost:8080/poc/helloService/</wsa:To>
    <wsa:ReplyTo>
      <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous
      </wsa:Address>
      <wsa:ReferenceParameters>
        <someRefParam xmlns="http://mycompany.com/test">12345678</someRefParam>
      </wsa:ReferenceParameters>
    </wsa:ReplyTo>
    <wsa:MessageID>urn:uuid:BE9E173A35BAB51CB31338454394298
    </wsa:MessageID>
    <wsa:Action>http://mycompany.com/Hello</wsa:Action>
  </soapenv:Header>
  <soapenv:Body>
    ...
  </soapenv:Body>
</soapenv:Envelope >

【讨论】:

Tommy,我在 jboss 中遇到的类似问题。我在这里问过这个问题。你能帮我吗?请***.com/questions/18148111/…【参考方案2】:

我找到了一种使用标准 JAX-WS 的方法。 获取端口时,同时使用 AddressingFeature 和 OneWayFeature。

AddressingFeature addressingfeature = new AddressingFeature();
OneWayFeature onewayfeature = new OneWayFeature(true, new WSEndpointReference(YOUR_REPLY_TO_ADDRESS, AddressingVersion.W3C));

// get the port
Hello hello = service.getHelloSoap11(addressingfeature, onewayfeature);

这将产生带有“ReplyTo”标签的消息。 您可能需要为此获取“com.sun.xml.ws:jaxws-rt”依赖项。

【讨论】:

以上是关于如何在 JAX-WS 客户端中指定 ReplyTo EndpointReference?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免在CXF或JAX-WS生成的Web服务客户端中指定WSDL位置?

如何在 WCF 测试客户端 (WcfTestClient.exe) 中指定列表参数?

如何使用 protobuf-net 反序列化 .asmx webservice 中指定的对象

Spring Cloud Bus,如何在 /bus/refresh?destination= 中指定多个目的地?

我们是不是需要在 WCF 服务器和客户端中指定相同的绑定?

如何在 CodeNameOne 项目中指定 abiFilters?