Search code examples
web-servicesjax-wsws-addressing

How to specify ReplyTo EndpointReference in a JAX-WS client?


I want to use JAX-WS API to create a WS-Addressing enabled web service client. I used wsimport to create the client stub from the WSDL file, and can enable/disable WS-Addressing by using the AddressingFeature, e.g.

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

However, I cannot find any samples in web that customize the WS-Addressing ReplyTo/FaultTo endpoint reference. Basically I want to create a WS request like the following (see the wsa:ReplyTo element):

<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>

I can add endpoint reference if using Spring Web Service client. However, I need to do it using JAX-WS. Any ideas?


Solution

  • I answer my own question.

    It seems that the standard JAX-WS API does not provide a convenient way to customize the WS-Addressing From/ReplyTo/FaultTo endpoint references. However, each JAX-WS runtime may provide additional proprietary API to set the headers.

    For example, the IBM JAX-WS RI provides an EndpointReferenceManager SPI to create the endpoint reference:

        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);
        }
    

    The above code, when running inside IBM Websphere, will produce a SOAP message like the following:

    <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 >