Develop the WSIF client - the Address Book Sample
Example
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
WSIFOperation - Asynchronous interactions reference