Sending transport headers with JAX-WS

You can enable an existing Java™ API for XML-Based Web Services (JAX-WS) web services client to send application-defined information along with your web services requests by using transport headers. In addition, you can enable a JAX-WS Web services endpoint to send application-defined information along with the Web services response message by using transport headers.

Before you begin

You need a JAX-WS web services client that you can enable to send transport headers.

Sending transport headers is supported in JAX-WS Web services clients, and is supported for the HTTP and JMS transports. The web services client must call the JAX-WS APIs directly and not through any intermediary layers, such as a gateway function.

About this task

When using the JAX-WS programming model, the client must set a property on the BindingProvider's RequestContext object to send values in transport headers with the Web services request message. After you set the property, the values are set in all the requests for subsequent remote method invocations against the BindingProvider object until the associated property is set to null or the BindingProvider object is discarded.

To send values in the transport headers on outbound requests from a JAX-WS Web services client application, modify the client code as follows:

Procedure

  1. Create a java.util.Map object that contains the transport headers.
  2. Add an entry to the Map object for each transport header that you want the client to send.
    1. Set the Map entry key to a string that exactly matches the transport header identifier.
      You can define the header identifier with a reserved header name, such as Cookie in the case of HTTP, or the header identifier can be user-defined, such as MyTransportHeader. Certain header identifiers are processed in a unique manner, but no other checks are made as to the header identifier value. To learn more about the HTTP header identifiers that have unique consideration, read about transport header properties best practices. You can find common header identifier string constants, such as HTTP_HEADER_SET_COOKIE in the com.ibm.websphere.webservices.Constants class.
    2. Set the Map entry value to the value of the transport header.
      The type of this value can be one of the following data types:
      • java.lang.String
      • java.lang.Integer
      • java.lang.Short
      • java.lang.Long
      • java.lang.Float
      • java.lang.Double
      • java.lang.Byte
      • java.lang.Boolean
  3. Set the Map object on the BindingProvider's RequestContext using the com.ibm.websphere.webservices.Constants.REQUEST_TRANSPORT_PROPERTIES property.
    When the REQUEST_TRANSPORT_PROPERTIES property value is set, that Map is used on subsequent invocations to set the header values in the outgoing requests. If the REQUEST_TRANSPORT_PROPERTIES property value is set to null, no transport properties are sent in outgoing requests. To learn more about these properties, see the transport header properties documentation.
  4. Issue remote method calls against the BindingProvider instance.
    The headers and the associated values from the Map are added to the outgoing request for each method invocation. If the invocation uses HTTP, then the transport headers are sent as HTTP headers within the HTTP request. If the invocation uses JMS, then the transport headers are sent as JMS message properties.
    If the Constants.REQUEST_TRANSPORT_PROPERTIES property is not set correctly, you might experience API usage errors that result in a WebServiceException error. The following requirements must be met, or the process fails:
    1. The Constants.REQUEST_TRANSPORT_PROPERTIES property value that is set on the BindingProvider's RequestContext must be a java.util.Map object or null.
    2. Each key in the Map must be a java.util.String data type.
    3. Each value in the Map must be one of the following data types:
      • java.lang.String
      • java.lang.Integer
      • java.lang.Short
      • java.lang.Long
      • java.lang.Float
      • java.lang.Double
      • java.lang.Byte
      • java.lang.Boolean

Results

You have a JAX-WS web services client that is configured to send transport headers in Web services request messages.

Example

Here is a short programming example that illustrates how request transport headers are sent by a JAX-WS Web services client application:
public class MyApplicationClass {
    // Inject an instance of the service's port-type.
    @WebServiceRef(EchoService.class)
    private EchoPortType port;

    // This method will invoke  the web service operation and send transport headers on the request.
    public void invokeService() {

        // Set up the Map that will contain the request headers.
        Map<String, Object> requestHeaders = new HashMap<String, Object>();
        requestHeaders.put(“MyHeader1”, “This is a string value”);
        requestHeaders.put(“MyHeader2”, new Integer(33));
        requestHeaders.put(“MyHeader3”, new Boolean(true));

        // Set the Map as a property on the RequestContext.
        BindingProvider bp = (BindingProvider) port;
        bp.getRequestContext().put(com.ibm.websphere.webservices.Constants.REQUEST_TRANSPORT_PROPERTIES, requestHeaders);

        // Invoke the web services operation.
        String result = port.echoString(“Hello, world!”);
    }
}

Sending response transport headers from a JAX-WS endpoint

Before you begin

You need a JAX-WS Web services endpoint implementation class that you can enable to send transport headers.

Sending response transport headers from a JAX-WS endpoint is similar to sending request transport headers from a JAX-WS client. It is supported for the HTTP and JMS transports.

About this task

When using the JAX-WS programming model, the endpoint implement class must set a property on the MessageContext to send values in transport headers with the Web services response message.

Procedure

  1. Create a java.util.Map object that contains the transport headers.
  2. Add an entry (key and value) to the Map object for each transport header that you want to send in the response message.
    This is similar to the previous procedure for the client.
  3. Retrieve the MessageContext (instance of javax.xml.ws.handler.MessageContext) associated with the invocation of the endpoint.
  4. Set the Map object on the MessageContext using the com.ibm.websphere.webservices.Constants.RESPONSE_TRANSPORT_PROPERTIES property.

Results

You have a JAX-WS Web services endpoint implementation class that is configured to send transport headers in Web services response messages.

Example

Here is a short programming example that illustrates how response transport headers are sent by a JAX-WS Web services endpoint implementation class:
@WebService
public class EchoServiceImpl implements EchoServicePortType {

    // Inject an instance of WebServiceContext so we can retrieve
    // the MessageContext for each invocation of this endpoint.
    @Resource
    WebServiceContext ctxt;

    /**
     * Default constructor.
     */
    public EchoServiceImpl() {
        ....
    }

    public String echoString(String input) {
        String result = “Echo result: “ + input;

        // Retrieve the MessageContext from the injected WebServiceContext.
        MessageContext mc = ctxt.getMessageContext();

        // Send some headers back in the response message.
        Map<String, Object> responseHeaders = new HashMap<String, Object>();
        responseHeaders.put("MyHeader1", "This is a string response value");
        responseHeaders.put("MyHeader2", new Integer(33));
        responseHeaders.put("MyHeader3”, new Boolean(false));

        // Set the response header Map on the MessageContext.
        mc.put(com.ibm.websphere.webservices.Constants.RESPONSE_TRANSPORT_PROPERTIES, responseHeaders);

        return result;
    }
}