Skip Headers

Oracle® Application Server Web Services Developer's Guide 10g Release 3 (10.1.3) B14434-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# 16 Processing SOAP Headers

This chapter describes the ways in which you can process SOAP headers:

- Processing SOAP Headers with Parameter Mapping

- Processing SOAP Headers by Using Handlers

- Processing SOAP Headers by Using the ServiceLifecycle Interface

## Processing SOAP Headers with Parameter Mapping

The WebServicesAssembler tool can be used to map SOAP header blocks defined in a `wsdl:binding` element of a WSDL file to method parameters in the generated service endpoint interface (SEI). This allows the SOAP header blocks to be accessed directly inside methods implementing the service endpoint interface.

Example 16-1 illustrates a simple WSDL that explicitly defines a SOAP header.

Example 16-1 Simple WSDL That Explicitly Defines a SOAP Header

    <definition xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://test.com"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"  xmlns:xs="http://www.w3.org/2001/XMLSchema"
    >
       <types/>
       <message name="HelloHeader">
          <part name="header" type="xs:string"/>
       </message>
       <message name="HelloMessage">
          <part name="body" type="xs:string"/>
       </message>
       message name="HelloMessageResponse"/>
       <portType name="HelloPortType">
          <operation name="sayHello">
             <input message="tns:HelloMessage"/>
             <output message="tns:HelloMessageResponse/>
             </operation>
          </portType>
          <binding name="HelloBinding" type="tns:HelloPortType">
             <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
             <operation name="sayHello">
                <input>
                   <soap:body use="literal" namespace="http://test.com"/>
                   <!--the SOAP header must be defined here -->
                   <soap:header message=""tns:HelloHeader" part="header" use="literal"/>
             </input>
             <output>
                <soap:body use="literal" namespace="http://test.com"/>
             </output>
          </operation>
       </binding>
       <service name="HelloService">
          <port name="HelloPort" binding="tns:HelloBinding">
             <soap:address location="http://localhost:8888/hello-service/hello-service"/>
          </port>
       </service>
    </definition>

The WebServicesAssembler argument for mapping SOAP headers to parameters is `mapHeadersToParameters`. The default for this argument is `true`, so there is no need to explicitly provide it unless you want to suppress the SOAP headers.

You can generate the service endpoint interface with parameter mapping by using either Ant tasks or the WebServicesAssembler tool. The following sample Ant task maps SOAP headers to parameters for the `hello-service` Web service.

    <oracle:topDownAssemble appName="hello-service"
                       wsdl="Hello.wsdl"
                       input="./classes"
                       output="build"
                       ear="dist/hello-service.ear"
                       packageName="oracle.demo "
                       mapHeadersToParameters="true"
                       >
                       <oracle:porttype className="oracle.demo.HelloImpl" />
    />

The following is the WebServicesAssembler command line version of the previous example.

    java -jar wsa.jar -topDownAssemble
                      -wsdl Hello.wsdl
                      -output build
                      -ear dist/hello-services.ear
                      -mapHeadersToParameters true
                      -packageName oracle.demo

## Processing SOAP Headers by Using Handlers

JAX-RPC Handlers can be used to process both explicit and implicit SOAP headers. Explicit SOAP headers are those defined in the WSDL document. Example 16-1 illustrates a simple WSDL that defines a SOAP header. Implicit SOAP headers are those that are not necessarily defined in any particular WSDL document, but may be present in a SOAP envelope.Handlers gain access to a SOAP header using the methods defined in the `javax.xml.rpc.handler.Handler` interface (see the JAX-RPC 1.1 specification available from: `http://java.sun.com/webservices/jaxrpc/index.jsp`). These methods are:

    boolean handleRequest(MessageContext context);
    boolean handleResponse(MessageContext context);
    boolean handleFault(MessageContext context);

The `context` argument in each of these messages can be used to view the SOAP headers in the SOAP envelope. The following is an example of a handler implementation viewing the headers on a SOAP request:

    boolean handleRequest(MessageContext context){
          javax.xml.rpc.handler.soap.SOAPMessageContext smc = (javax.xml.rpc.handler.soap.SOAPMessageContext)context;
          javax.xml.soap.SOAPHeader sh = smc.getSOAPMessage.getSOAPHeader();
          //the SOAPHeader will contain a list of SOAPHeaderElements (header blocks)
          Iterator it = sh.examineAllHeaderElements();
          //iterate through all the SOAP header elements and print their names
          while(it.hasNext()){
                javax.xml.soap.SOAPHeaderElement elem = (SOAPHeaderElement)it.next();
                System.out.println(elem.getElementName().getQualifiedName());
          }
          return true;
    }

For information on processing messages directly, see the SOAP with Attachments API for Java (SAAJ) at the following Web address:

`http://java.sun.com/webservices/saaj/index.jsp`

## Processing SOAP Headers by Using the ServiceLifecycle Interface

You can manage the life cycle of the service endpoint by implementing the `javax.xml.rpc.server.ServiceLifecycle` interface. The interface has the following methods.

    void init(Object context);
    void destroy();

The runtime system will invoke the `init` method and pass a context object. Example 16-2 demonstrates how to use the `javax.xml.rpc.server.ServiceLifecycle` interface to access SOAP headers:

Example 16-2 Using ServiceLifecycle to Access SOAP Headers

    public class HelloImpl implements HelloPortType,ServiceLifecycle{
          private Object m_context;

          public void sayHello(String body){
                javax.xml.rpc.server.ServletEndpointContext sec = (ServletEndpointContext)m_context;
                javax.xml.rpc.handler.soap.SOAPMessageContext mc = (SOAPMessageContext)sec.getMessageContext();
                javax.xml.soap.SOAPHeader sh = mc.getSOAPMessage().getSOAPHeader();
                 // from here you can process all the header
                 // blocks in the SOAP header.
    }

          //this will be called by the runtime system.
          public void init(Object context){
          m_context = context;
          }
          public void destroy(){
          }
    }

Implementing this interface enables you to process both implicit and explicit SOAP headers, although it is more useful for the implicit headers.

### Getting HTTP Headers with the ServiceLifecycle Interface

The `HTTP_SERVLET_REQUEST` property in the `oracle.webservices.ServerConstants` class enables you to access the HTTP message header. This property can be used by a service implementation class to get the HTTP servlet request when the caller of the Web service uses HTTP transport.

To use this property, the service implementation must implement `javax.xml.rpc.server.ServiceLifecyle` and store the `Object` passed into the `init` method which is an instance of `javax.xml.rpc.server.ServletEndpointContext`.

When a method in the service implementation class is invoked, the `ServletEndpointContext.``getMessageContext` method returns a `javax.xml.rpc.handler.MessageContext`. The `MessageContext`.`getProperty` method can use `HTTP_SERVLET_REQUEST` as a property name. The returned object is an instance of `javax.servlet.http.HttpServletRequest`.

Example 16-3 illustrates how to get an HTTP header to obtain the IP address. In the example, the `HelloImpl` class implements the `ServiceLifecycle` interface. In this case, the `context` object passed to the `init` method is cast to the `ServletEndpointContext` object. The `destroy` method destroys the service lifecycle. In the implementation of the `getIPAddress` method, the `getMessageContext` method pulls the message context from the `ServletEndpointContext` object. The `getProperty` method uses the `HTTP_SERVLET_REQUEST` property to return the request as an `HttpServletRequest` object. The `getRemoteAddr` method returns the IP address.

Example 16-3 Getting an HTTP Header

    public class HelloImpl implements ServiceLifecycle  {
       ServletEndpointContext m_context;
       public void init(Object context) throws ServiceException {
           m_context = (ServletEndpointContext)context;
       }

       public void destroy() {
        }

       public String getIPAddress(){
          HttpServletRequest request = (HttpServletRequest)m_context.
              getMessageContext().getProperty(ServerConstants.HTTP_SERVLET_REQUEST);
          return request.getRemoteAddr();
       }

    }

## Limitations

See "Processing SOAP Headers".

## Additional Information

For more information on:

- assembling Web services from a WSDL, see Chapter 5, "Assembling a Web Service from a WSDL".

- assembling stateful Web services, see Chapter 6, "Assembling a Web Service with Java Classes".

  assembling Web services from EJBs, see Chapter 7, "Assembling a Web Service with EJBs".

- assembling Web services from a JMS queue or topic, see Chapter 8, "Assembling Web Services with JMS Destinations".

- assembling Web services from database resources, see Chapter 9, "Developing Database Web Services".

- assembling Web services with J2SE 5.0 Annotations, see Chapter 10, "Assembling Web Services with Annotations".