Oracle® Application Server Web Services Developer's Guide 10g (10.1.3.1.0) Part Number B28974-01 |
|
|
View PDF |
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 17-1 illustrates a simple WSDL that explicitly defines a SOAP header.
Example 17-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 tool provides the boolean mapHeadersToParameters
argument for mapping SOAP headers to parameters. 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" /> </oracle:topDownAssemble>
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
In this command and Ant task:
topDownAssemble
—Creates the required classes and deployment descriptors for a Web service based on a WSDL description. The files can be stored in either an EAR file, a WAR file, or a directory. See topDownAssemble.
wsdl
—Specifies the absolute file path, relative file path, or URL to a WSDL document. See "wsdl".
output
—Specifies the directory where generated files will be stored. If the directory does not exist, it will be created. See "output".
ear
—Specifies the name and location of the generated EAR. See "ear".
mapHeadersToParameters
—Indicates if SOAP headers defined in the WSDL should be mapped to parameters for each of the methods in the generated Java code. See "mapHeadersToParameters".
packageName
—Specifies the package name that will be used for generated classes if no package name is declared in the JAX-RPC mapping file. See "packageName".
The following WebServicesAssembler commands and Ant tasks can be used to call the mapHeaderstoParameters
argument. For more information on these commands, see Chapter 18, "Using WebServicesAssembler".
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 17-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. 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; }
See Also:
|
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. The context
object contains the ServletEndpointContext
object. From this object, you can extract the SOAPMessageContext
to process the header upon each invocation.
Example 17-2 demonstrates how to use the javax.xml.rpc.server.ServiceLifecycle
interface to access SOAP headers:
Example 17-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 following sections describe how static stub and Dynamic Invocation Interface (DII) clients can obtain the headers from HTTP response and requests.
How Stub Clients Can Get Headers with the ServiceLifecycle Interface
How DII Clients Can Get Headers with the OracleCall Interface
J2SE and J2EE static stub clients can use the HTTP_SERVLET_REQUEST
and HTTP_SERVLET_RESPONSE
properties in the oracle.webservices.ServerConstants
class to access the HTTP message header. This property can be used by a service implementation class to get the HTTP servlet request or response when the Web service caller uses HTTP transport.
To use either of these properties, 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 either HTTP_SERVLET_REQUEST
or HTTP_SERVLET_RESPONSE
as a property name.
If HTTP_SERVLET_REQUEST
is the requested property, then the returned object is an instance of javax.servlet.http.HttpServletRequest
. If HTTP_SERVLET_RESPONSE
is the requested property, then the returned object is an instance of javax.servlet.http.HttpServletResponse
.
Example 17-3 illustrates how to get an HTTP request 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 17-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();
}
}
Dynamic Invocation Interface (DII) clients can use methods in the oracle.webservices.OracleCall
interface to obtain HTTP request and response headers. To retrieve response headers, use the getResponseHeaders()
method. This method returns a Vector
; the elements in the Vector
are the SOAP response headers.
To retrieve request headers use the getHeaders()
method. This method also returns a Vector
where the elements are the SOAP response headers. Typically, the headers are added to the Vector
with the addHeaders()
method.
Example 17-4 illustrates DII client code for getting the response headers.
Example 17-4 Retrieving Response Headers in DII Client Code
...
OracleCall call = (OracleCall)port.getCall();
Vector headers = call.getResponseHeaders();
if (Vector != null) {
for(int i = 0;i < headers.size();i++) {
Element header = (Element) headers.get(i);
// do something with the header Element
...
}
}
...
For information on how message headers can be retrieved by DII clients of Web Services Invocation Framework (WSIF) services, see "How DII Clients of WSIF Services Can Get Message Headers" in the Oracle Application Server Advanced Web Services Developer's Guide.
For more information on:
assembling Web services from a WSDL, see Chapter 6, "Assembling a Web Service from WSDL".
assembling stateful Web services, see Chapter 7, "Assembling a Web Service with Java Classes".
assembling Web services from EJBs, see Chapter 8, "Assembling a Web Service with EJBs".
assembling Web services from a JMS queue or topic, see Chapter 9, "Assembling Web Services with JMS Destinations".
assembling Web services from database resources, see Chapter 10, "Assembling Database Web Services".
assembling Web services with J2SE 5.0 Annotations, see Chapter 11, "Assembling Web Services with Annotations".