This is a simple example that will show you how to develop a Web service client
and server, which sends or receives SOAP headers. First, we define a WSDL that uses
soap:header
elements to specify that particular parameters will be sent
in the SOAP message's HEADER section rather than under the BODY element.
Below is the WSDL for the example. The header parameters are specified in the
binding section of the WSDL. The soap:header
element specifies which
part of which message is going to be header parameter.
<?xml version="1.0" encoding="UTF-8"?> <definitions name="HeaderService" targetNamespace="http://www.headerWSDL" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.headerWSDL" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <types/> <message name="echoHeaderRequest"> <part name="arg0" type="xsd:string"/> </message> <message name="echoHeaderResponse"> <part name="arg1" type="xsd:string"/> </message> <portType name="Header"> <operation name="echoHeader"> <input message="tns:echoHeaderRequest"/> <output message="tns:echoHeaderResponse"/> </operation> </portType> <binding name="HeaderBinding" type="tns:Header"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="echoHeader"> <soap:operation soapAction="http://www.headerWSDL/echoHeader"/> <input> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://www.headerWSDL" use="encoded"/> <soap:header message="tns:echoHeaderRequest" part="arg0" use="encoded"/> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://www.headerWSDL" use="encoded"/> <soap:header message="tns:echoHeaderResponse" part="arg1" use="encoded"/> </output> </operation> </binding> <service name="HeaderService"> <port binding="tns:HeaderBinding" name="EchoHeaderPort"> <soap:address location="http://localhost:9090/header"/> </port> </service> </definitions>
When you specify the header parameters in WSDL and compile it, the header parameters become arguments of the remote method similar to the regular BODY parameters. You can invoke operations that use header parameters in the same fashion as you invoke operations having BODY parameters only.
package header; public class Client { public static void main(String[] args) throws Exception { | javax.naming.InitialContext ctx = new javax.naming.InitialContext(); | HeaderService service = (HeaderService) | ctx.lookup("xmlrpc:soap:header.HeaderService"); | | Header stub = service.getEchoHeaderPort(); | ((javax.xml.rpc.Stub)stub)._setProperty("javax.xml.rpc.service.endpoint.address", | args.length > 0 ? args[0] : "http://localhost:9090/header"); | | echoHeader(stub); } public static void echoHeader(Header stub) { | try | { | | String i0 = "Hello Header!"; | | String result = stub.echoHeader(i0); | | System.out.println("echoHeader = " + result); | } | catch (java.rmi.RemoteException ex) | { | | System.out.println("error invoking echoHeader:" + ex.getMessage()); | | if (System.getProperty("DEBUG") != null) | | ex.printStackTrace(); | } } }
When using the Call
interface you need to set certain properties
in order to specify that certain parameters should go into the SOAP header instead
of the body. The CallClient
class listed below shows how to add header
parameters to a call. It sets the HEADERS
property on the call object.
The HEADERS
property value must be a boolean array where each element
in the array should be set to true if the particular parameter is a header parameter.
The elements of the array must be in the same order as that of added parameters to the
call object. If you have a return value coming back from the invocation, you must
increase the length of the array by 1 and set the last element to true if the return
value is present under header.
package header; public class CallClient { public static void main(String[] args) throws Exception { | System.setProperty(javax.xml.rpc.ServiceFactory.SERVICEFACTORY_PROPERTY, | "com.sssw.jbroker.web.xml.rpc.ServiceFactoryDelegate"); | javax.xml.rpc.ServiceFactory factory = javax.xml.rpc.ServiceFactory.newInstance(); | javax.xml.namespace.QName qname = new javax.xml.namespace.QName("http://www.headerWSDL", "HeaderService"); | javax.xml.rpc.Service service = factory.createService(qname); | javax.xml.namespace.QName portName = new javax.xml.namespace.QName("http://www.headerWSDL", "HeaderPort"); | | String url = args.length > 0 ? args[0] : | "http://localhost:9090/header"; | | echoHeader(service, portName, url); } public static void echoHeader(javax.xml.rpc.Service service, javax.xml.namespace.QName portName, String url) throws Exception { | try | { | | javax.xml.rpc.Call call = service.createCall(portName); | | javax.xml.namespace.QName i0 = | | new javax.xml.namespace.QName("", "arg0"); | | call.addParameter("arg0", i0, String.class, | | javax.xml.rpc.ParameterMode.IN); | | javax.xml.namespace.QName r = | | new javax.xml.namespace.QName("", "arg1"); | | call.setReturnType(r, String.class); | | String iv0 = "Hello Header!"; | | | | Object[] parms = { iv0 }; | | | | call.setTargetEndpointAddress(url); | | call.setProperty(javax.xml.rpc.Call.SOAPACTION_URI_PROPERTY, | | "http://www.headerWSDL/echoHeader"); | | call.setProperty( | | javax.xml.rpc.Call.OPERATION_STYLE_PROPERTY, "rpc"); | | call.setOperationName(new javax.xml.namespace.QName( | | "http://www.headerWSDL", "echoHeader")); | | | | boolean[] headers = new boolean[2]; | | headers[0] = true; | | headers[1] = true; | | | | call.setProperty( | | com.sssw.jbroker.web.portable.Stub.HEADERS, headers); | | | | String result = (String) call.invoke(parms); | | System.out.println("echoHeader = " + result); | } | catch (java.rmi.RemoteException ex) | { | | System.out.println("error invoking echoHeader:" + ex.getMessage()); | | if (System.getProperty("DEBUG") != null) | | ex.printStackTrace(); | } } }
Since the header parameters become the arguments of the remote method, writing the server implementation is similar to writing it for BODY parameters only. You simply have to implement the interface.
package header; public class Server extends Header_ServiceSkeleton { public String echoHeader(String i0) throws java.rmi.RemoteException { | return i0; } }
Please look at README file of the example for how to build and run the example.
Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.