Develop the WSIF client - the Address Book Sample

 

+

Search Tips   |   Advanced Search

 

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