Skip Headers
Oracle® Application Server Web Services Developer's Guide
10g Release 3 (10.1.3)
B14434-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

16 Processing SOAP Headers

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

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: