Oracle® Application Server Web Services Developer's Guide 10g Release 3 (10.1.3) B14434-01 |
|
![]() Previous |
![]() Next |
This chapter describes the ways in which you can process SOAP headers:
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
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:
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.
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();
}
}
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".