Develop the WSIF client - the Address Book Sample
The code fragments in this topic show you how to use the Web Services Invocation Framework (WSIF) API to invoke the AddressBook Sample Web service dynamically.
Usage Scenario
This is example code for dynamic invocation of the AddressBook sample Web service using WSIF
try { String wsdlLocation="clients/addressbook/AddressBookSample.wsdl"; // The starting point for any dynamic invocation using wsif is a // WSIFServiceFactory. We create ourselves one via the newInstance // method. WSIFServiceFactory factory = WSIFServiceFactory.newInstance(); // Once we have a factory, we can use it to create a WSIFService object // corresponding to the AddressBookService service in the wsdl file. // Note: since we only have one service defined in the wsdl file, we // do not need to use the namespace and name of the service and can pass // null instead. This also applies to the port type, although values have // been used below for illustrative purposes. WSIFService service = factory.getService( wsdlLocation, // location of the wsdl file null, // service namespace null, // service name "http://www.ibm.com/namespace/wsif/samples/ab", // port type namespace "AddressBookPT" // port type name ); // The AddressBook.wsdl file contains the definitions for two complexType // elements within the schema element. We will now map these complexTypes // to Java classes. These mappings are used by the Apache SOAP provider service.mapType( new javax.xml.namespace.QName( "http://www.ibm.com/namespace/wsif/samples/ab/types", "address"), Class.forName("com.ibm.www.namespace.wsif.samples.ab.types.WSIFAddress")); service.mapType( new javax.xml.namespace.QName( "http://www.ibm.com/namespace/wsif/samples/ab/types", "phone"), Class.forName("com.ibm.www.namespace.wsif.samples.ab.types.WSIFPhone")); // We now have a WSIFService object. The next step is to create a WSIFPort // object for the port we wish to use. The getPort(String portName) method // allows us to generate a WSIFPort from the port name. WSIFPort port = null; if (portName != null) { port = service.getPort(portName); } if (port == null) { // If no port name was specified, attempt to create a WSIFPort from // the available ports for the port type specified on the service port = getPortFromAvailablePortNames(service); } // Once we have a WSIFPort, we can create an operation. We are going to execute // the addEntry operation and therefore we attempt to create a WSIFOperation // corresponding to it. The addEntry operation is overloaded in the wsdl ie. // there are two versions of it, each taking different parameters (parts). // This overloading requires that we specify the input and output message // names for the operation in the createOperation method so that the correct // operation can be resolved. // Since the addEntry operation has no output message, we use null for its name. WSIFOperation operation = port.createOperation("addEntry", "AddEntryWholeNameRequest", null); // Create messages to use in the execution of the operation. This should // be done by invoking the createXXXXXMessage methods on the WSIFOperation. WSIFMessage inputMessage = operation.createInputMessage(); WSIFMessage outputMessage = operation.createOutputMessage(); WSIFMessage faultMessage = operation.createFaultMessage(); // Create a name and address to add to the addressbook String nameToAdd="Chris P. Bacon"; WSIFAddress addressToAdd = new WSIFAddress (1, "The Waterfront", "Some City", "NY", 47907, new WSIFPhone (765, "494", "4900")); // Add the name and address to the input message inputMessage.setObjectPart("name", nameToAdd); inputMessage.setObjectPart("address", addressToAdd); // Execute the operation, obtaining a flag to indicate its success boolean operationSucceeded = operation.executeRequestResponseOperation( inputMessage, outputMessage, faultMessage); if (operationSucceeded) { System.out.println("Successfully added name and address to addressbook\n"); } else { System.out.println("Failed to add name and address to addressbook"); } // Start from fresh operation = null; inputMessage = null; outputMessage = null; faultMessage = null; // This time we will lookup an address from the addressbook. // The getAddressFromName operation is not overloaded in the // wsdl and therefore we can simply specify the operation name // without any input or output message names. operation = port.createOperation("getAddressFromName"); // Create the messages inputMessage = operation.createInputMessage(); outputMessage = operation.createOutputMessage(); faultMessage = operation.createFaultMessage(); // Set the name to find in the addressbook String nameToLookup="Chris P. Bacon"; inputMessage.setObjectPart("name", nameToLookup); // Execute the operation operationSucceeded = operation.executeRequestResponseOperation( inputMessage, outputMessage, faultMessage); if (operationSucceeded) { System.out.println("Successful lookup of name '"+nameToLookup+"' in addressbook"); // We can obtain the address that was found by querying the output message WSIFAddress addressFound = (WSIFAddress) outputMessage.getObjectPart("address"); System.out.println("The address found was:"); System.out.println(addressFound); } else { System.out.println("Failed to lookup name in addressbook"); } } catch Exception(e) { System.out.println("An exception occurred when running the sample:"); e.printStackTrace(); } }The preceding code refers to the following Sample method
WSIFPort getPortFromAvailablePortNames(WSIFService service) throws WSIFException { String portChosen = null; // Obtain a list of the available port names for the service Iterator it = service.getAvailablePortNames(); { System.out.println("Available ports for the service are: "); while (it.hasNext()) { String nextPort = (String) it.next(); if (portChosen == null) portChosen = nextPort; System.out.println(" - " + nextPort); } } if (portChosen == null) { throw new WSIFException("No ports found for the service!"); } System.out.println("Using port " + portChosen + "\n"); // An alternative way of specifying the port to use on the service // is to use the setPreferredPort method. Once a preferred port has // been set on the service, a WSIFPort can be obtained via getPort // (no arguments). If a preferred port has not been set and more than // one port is available for the port type specified in the WSIFService, // an exception is thrown. service.setPreferredPort(portChosen); WSIFPort port = service.getPort(); return port; }The Web service uses the following classes...
WSIFAddress
public class WSIFAddress implements Serializable { //instance variables private int streetNum; private java.lang.String streetName; private java.lang.String city; private java.lang.String state; private int zip; private WSIFPhone phoneNumber; //constructors public WSIFAddress () { } public WSIFAddress (int streetNum, java.lang.String streetName, java.lang.String city, java.lang.String state, int zip, WSIFPhone phoneNumber) { this.streetNum = streetNum; this.streetName = streetName; this.city = city; this.state = state; this.zip = zip; this.phoneNumber = phoneNumber; } public int getStreetNum() { return streetNum; } public void setStreetNum(int streetNum) { this.streetNum = streetNum; } public java.lang.String getStreetName() { return streetName; } public void setStreetName java.lang.String(streetName) { this.streetName = streetName; } public java.lang.String getCity() { return city; } public void setCity java.lang.String(city) { this.city = city; } public java.lang.String getState() { return state; } public void setState java.lang.String(state) { this.state = state; } public int getZip() { return zip; } public void setZip(int zip) { this.zip = zip; } public WSIFPhone getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(WSIFPhone phoneNumber) { this.phoneNumber = phoneNumber; } }WSIFPhone
public class WSIFPhone implements Serializable { //instance variables private int areaCode; private java.lang.String exchange; private java.lang.String number; //constructors public WSIFPhone () { } public WSIFPhone (int areaCode, java.lang.String exchange, java.lang.String number) { this.areaCode = areaCode; this.exchange = exchange; this.number = number; } public int getAreaCode() { return areaCode; } public void setAreaCode(int areaCode) { this.areaCode = areaCode; } public java.lang.String getExchange() { return exchange; } public void setExchange java.lang.String(exchange) { this.exchange = exchange; } public java.lang.String getNumber() { return number; } public void setNumber java.lang.String(number) { this.number = number; } }WSIFAddressBook
public class WSIFAddressBook { private Hashtable name2AddressTable = new Hashtable(); public WSIFAddressBook() { } public void addEntry(String name, WSIFAddress address) { name2AddressTable.put(name, address); } public void addEntry(String firstName, String lastName, WSIFAddress address) { name2AddressTable.put(firstName+" "+lastName, address); } public WSIFAddress getAddressFromName(String name) throws IllegalArgumentException { if (name == null) { throw new IllegalArgumentException("The name argument must not be " + "null."); } return (WSIFAddress)name2AddressTable.get(name); } }The following code is the corresponding WSDL file for the Web service
<?xml version="1.0" ?> <definitions targetNamespace="http://www.ibm.com/namespace/wsif/samples/ab" xmlns:tns="http://www.ibm.com/namespace/wsif/samples/ab" xmlns:typens="http://www.ibm.com/namespace/wsif/samples/ab/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:format="http://schemas.xmlsoap.org/wsdl/formatbinding/" xmlns:java="http://schemas.xmlsoap.org/wsdl/java/" xmlns:ejb="http://schemas.xmlsoap.org/wsdl/ejb/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <xsd:schema targetNamespace="http://www.ibm.com/namespace/wsif/samples/ab/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:complexType name="phone"> <xsd:element name="areaCode" type="xsd:int"/> <xsd:element name="exchange" type="xsd:string"/> <xsd:element name="number" type="xsd:string"/> </xsd:complexType> <xsd:complexType name="address"> <xsd:element name="streetNum" type="xsd:int"/> <xsd:element name="streetName" type="xsd:string"/> <xsd:element name="city" type="xsd:string"/> <xsd:element name="state" type="xsd:string"/> <xsd:element name="zip" type="xsd:int"/> <xsd:element name="phoneNumber" type="typens:phone"/> </xsd:complexType> </xsd:schema> </types> <message name="AddEntryWholeNameRequestMessage"> <part name="name" type="xsd:string"/> <part name="address" type="typens:address"/> </message> <message name="AddEntryFirstAndLastNamesRequestMessage"> <part name="firstName" type="xsd:string"/> <part name="lastName" type="xsd:string"/> <part name="address" type="typens:address"/> </message> <message name="GetAddressFromNameRequestMessage"> <part name="name" type="xsd:string"/> </message> <message name="GetAddressFromNameResponseMessage"> <part name="address" type="typens:address"/> </message> <portType name="AddressBookPT"> <operation name="addEntry"> <input name="AddEntryWholeNameRequest" message="tns:AddEntryWholeNameRequestMessage"/> </operation> <operation name="addEntry"> <input name="AddEntryFirstAndLastNamesRequest" message="tns:AddEntryFirstAndLastNamesRequestMessage"/> </operation> <operation name="getAddressFromName"> <input name="GetAddressFromNameRequest" message="tns:GetAddressFromNameRequestMessage"/> <output name="GetAddressFromNameResponse" message="tns:GetAddressFromNameResponseMessage"/> </operation> </portType> <binding name="SOAPHttpBinding" type="tns:AddressBookPT"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="addEntry"> <soap:operation soapAction=""/> <input name="AddEntryWholeNameRequest"> <soap:body use="encoded" namespace="http://www.ibm.com/namespace/wsif/samples/ab" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input> </operation> <operation name="addEntry"> <soap:operation soapAction=""/> <input name="AddEntryFirstAndLastNamesRequest"> <soap:body use="encoded" namespace="http://www.ibm.com/namespace/wsif/samples/ab" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input> </operation> <operation name="getAddressFromName"> <soap:operation soapAction=""/> <input name="GetAddressFromNameRequest"> <soap:body use="encoded" namespace="http://www.ibm.com/namespace/wsif/samples/ab" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input> <output name="GetAddressFromNameResponse"> <soap:body use="encoded" namespace="http://www.ibm.com/namespace/wsif/samples/ab" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation> </binding> <binding name="JavaBinding" type="tns:AddressBookPT"> <java:binding/> <format:typeMapping encoding="Java" style="Java"> <format:typeMap typeName="typens:address" formatType="com.ibm.www.namespace.wsif.samples.ab.types.WSIFAddress"/> <format:typeMap typeName="xsd:string" formatType="java.lang.String"/> </format:typeMapping> <operation name="addEntry"> <java:operation methodName="addEntry" parameterOrder="name address" methodType="instance"/> <input name="AddEntryWholeNameRequest"/> </operation> <operation name="addEntry"> <java:operation methodName="addEntry" parameterOrder="firstName lastName address" methodType="instance"/> <input name="AddEntryFirstAndLastNamesRequest"/> </operation> <operation name="getAddressFromName"> <java:operation methodName="getAddressFromName" parameterOrder="name" methodType="instance" returnPart="address"/> <input name="GetAddressFromNameRequest"/> <output name="GetAddressFromNameResponse"/> </operation> </binding> <binding name="EJBBinding" type="tns:AddressBookPT"> <ejb:binding/> <format:typeMapping encoding="Java" style="Java"> <format:typeMap typeName="typens:address" formatType="com.ibm.www.namespace.wsif.samples.ab.types.WSIFAddress"/> <format:typeMap typeName="xsd:string" formatType="java.lang.String"/> </format:typeMapping> <operation name="addEntry"> <ejb:operation methodName="addEntry" parameterOrder="name address" interface="remote"/> <input name="AddEntryWholeNameRequest"/> </operation> <operation name="addEntry"> <ejb:operation methodName="addEntry" parameterOrder="firstName lastName address" interface="remote"/> <input name="AddEntryFirstAndLastNamesRequest"/> </operation> <operation name="getAddressFromName"> <ejb:operation methodName="getAddressFromName" parameterOrder="name" interface="remote" returnPart="address"/> <input name="GetAddressFromNameRequest"/> <output name="GetAddressFromNameResponse"/> </operation> </binding> <service name="AddressBookService"> <port name="SOAPPort" binding="tns:SOAPHttpBinding"> <soap:address location="http://localhost/wsif/samples/addressbook/soap/servlet/rpcrouter"/> </port> <port name="JavaPort" binding="tns:JavaBinding"> <java:address className="services.addressbook.WSIFAddressBook"/> </port> <port name="EJBPort" binding="tns:EJBBinding"> <ejb:address className="services.addressbook.ejb.AddressBookHome" jndiName="ejb/samples/wsif/AddressBook" classLoader="services.addressbook.ejb.AddressBook.ClassLoader"/> </port> </service> </definitions>
See Also
Developing a WSIF service
WSIFOperation - Asynchronous interactions reference