WSIF-Service entwickeln

Ein WSIF-Service (Web Services Invocation Framework) ist ein Web-Service, der WSIF verwendet.

Informationen zu diesem Vorgang

Wenn Sie einen WSIF-Service entwickeln möchten, müssen Sie zunächst den Web-Service erstellen (oder einen vorhandenen Web-Service verwenden) und dann den WSIF-Client ausgehend vom WSDL-Dokument für diesen Web-Service entwickeln.

Außerdem gibt es zwei bereits erstellte WSIF-Muster, die zum Download auf der Seite mit den Mustern zu WebSphere Application Server auf der developerWorks-Website zur Verfügung stehen.

  • AddressBook
  • StockQuote

Weitere Informationen zur Verwendung dieser Muster können Sie der Dokumentation entnehmen, die im developerWorks-Downloadpaket enthalten ist. Beachten Sie, dass diese Muster für WebSphere Application Server Version 5 geschrieben wurden.

Gehen Sie wie folgt vor, um einen WSIF-Service zu entwickeln:

Vorgehensweise

  1. Implementieren Sie den Web-Service.

    Zum Ermitteln, Erstellen und Veröffentlichen des Web-Service können Sie die Web-Service-Tools verwenden. Sie können Java-Bean-, Enterprise-Bean- und URL-Web-Services entwickeln. Mit den Web-Service-Tools können Sie Java-Beispielcode und eine Beispielanwendung auf der Basis eines WSDL-Dokuments erstellen. Eine Enterprise-Bean kann beispielsweise als ein Web-Service angeboten werden, mit RMI/IIOP (Remote Method Invocation over Internet Inter-ORB Protocol) als Zugriffsprotokoll. Sie können auch eine Java-Klasse als Web-Service verwenden, mit nativen Java-Aufrufen als Zugriffsprotokoll.

    [AIX Solaris HP-UX Linux Windows][z/OS]Mit WebSphere Studio Application Developer können Sie aus einer Java-Anwendung einen Web-Service erstellen. Eine diesbezügliche Beschreibung finden Sie in den Lerntexten zum Service "StockQuote". Die in diesem Szenario verwendete Java-Anwendung gibt den letzten Handelspreis von der Internetwebsite "www.xmltoday.com" zurück, dem ein Aktiensymbol zugeordnet ist. Mit dem Assistenten für Web-Services generieren Sie aus der Bean StockQuoteService.java ein WSDL-Bindungsdokument mit dem Namen StockQuoteService-binding.wsdl und ein WSDL-Servicedokument mit dem Namen StockQuoteService-service.wsdl. Anschließend implementieren Sie den Web-Service in einem Web-Server, generieren einen Client-Proxy zu dem Web-Service und eine Beispielanwendung, die über den Client-Proxy auf den Service "StockQuoteService" zugreift. Sie werden den Web-Service "StockQuote" testen, ihn mit dem IBM UDDI-Explorer veröffentlichen und anschließend in der IBM UDDI-Testregistry nach dem Web-Service "StockQuote" suchen.

    [IBM i]Sie können WebSphere Development Studio for System i (WDS) verwenden, um aus einer Java-Anwendung einen Web-Service zu erstellen. Mit dem Assistenten für Web-Services können Sie aus der Java-Bean ein WSDL-Dokument für Bindungen und ein WSDL-Dokument für Services generieren. Anschließend können Sie den Web-Service in einem Web-Server implementieren, einen Client-Proxy für den Web-Service generieren und eine Beispielanwendung generieren, die über den Client-Proxy auf den Service zugreift. Sie können den Service testen, ihn mit IBM UDDI-Explorer veröffentlichen und anschließend den Service in der IBM UDDI-Testregistry erkennen.

  2. WSIF-Client entwickeln.
    Die folgenden Informationen sind hilfreich, wenn Sie einen WSIF-Client entwickeln möchten:

    Das Beispiel AddressBook wurde für synchrone Interaktion geschrieben. Wenn Sie einen JMS-Provider verwenden, muss Ihr WSIF-Client möglicherweise asynchron agieren. WSIF stellt im Wesentlichen zwei Features bereit, die diese Anforderung erfüllen:

    • Ein Korrelationsservice, der Nachrichten IDs zuordnet, so dass eine Anforderung einer (eventuell gegebenen) Antwort zugeordnet werden kann.
    • Eine Antwort-Handler, die die Antwort später vom Web-Service abruft.
    Weitere Informationen finden Sie im Artikel WSIFOperation - Referenz auf asynchrone Interaktionen.

Beispiel: Mit WSIF den Beispiel-Web-Service "AddressBook" dynamisch aufrufen

Der folgende Beispielcode zeigt den dynamischen Aufruf des Beispiel-Web-Service AddressBook mit WSIF:

    try  {
        String wsdlLocation="clients/addressbook/AddressBookSample.wsdl";

        //Der Ausgangspunkt für dynamische Aufrufe mit WSIF ist eine
        //WSIFServiceFactory. Hier wird eine solche mit der Methode
        //newInstance erstellt.
                WSIFServiceFactory factory = WSIFServiceFactory.newInstance();

        //Anschließend kann mit der Factory ein WSIFService-Objekt erstellt werden,
        //das dem Service AddressBookService in der wsdl-Datei entspricht.
        // Anmerkung: Da in der wsdl-Datei nur ein Service definiert ist, müssen
        //Namespace und Name des Service nicht verwendet werden. Stattdessen kann
        //null übergeben werden. Dasselbe gilt für den Porttyp, obwohl hier zur
        //Veranschaulichung Werte verwendet werden.
                WSIFService service = factory.getService(
            wsdlLocation,    // Position der wsdl-Datei 
            null,            // Service-Namespace
            null,            // Servicename
           "http://www.ibm.com/namespace/wsif/samples/ab", // Namespace des portType
            "AddressBookPT" // Name des portType
        );

        // Die Datei AddressBook.wsdl enthält die Definitionen für zwei complexType-Elemente
        // innerhalb des Eintrags schema. Diese Elemente werden jetzt Java-Klassen zugeordnet.
        // Diese Zuordnungen werden vom Apache-SOAP-Provider verwendet.
        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"));
            // Jetzt liegt ein WSIFService-Objekt vor. Als nächstes wird ein WSIFPort-
            // Objekt für den zu verwendenden Port erstellt. Mit der Methode
                  // getPort(String portName) kann ein WSIFPort aus dem Portnamen erstellt werden.
                WSIFPort port = null;

        if (portName != null) {
            port = service.getPort(portName);
        }
        if (port == null) {
            // Wenn kein Portname angegeben wurde, kann versucht werden, einen WSIFPort aus den Ports
                  // zu erstellen, die für den Porttyp, der für den Service angegeben wurde, verfügbar sind.
                        port = getPortFromAvailablePortNames(service);
        }

        // Mit dem WSIFPort kann eine Operation erstellt werden. Hier soll die Operation
        // addEntry ausgeführt und daher versucht werden, eine entsprechende WSIFOperation
        // zu erstellen. Die Operation addEntry in der wsdl ist überladen. Es sind zwei
        // Versionen mit unterschiedlichen Parametern (Abschnitten) vorhanden.
		        // Deshalb müssen die Namen der Ein- und Ausgabenachricht für die Operation
        // in der Methode createOperation angegeben werden, damit die richtige Operation
        // aufgelöst werden kann.
        // Da die Operation addEntry keine Ausgabenachricht hat, wird als Name null verwendet.
        WSIFOperation operation =
            port.createOperation("addEntry", "AddEntryWholeNameRequest", null);

        // Es werden Nachrichten für den Verlauf der Operation erstellt. Dazu werden die Methoden
            // createXXXXXMessage für die WSIFOperation aufgerufen.
                WSIFMessage inputMessage = operation.createInputMessage();
        WSIFMessage outputMessage = operation.createOutputMessage();
        WSIFMessage faultMessage = operation.createFaultMessage();

        // Es werden ein Name und eine Adresse erstellt und zum Adressbuch hinzugefügt.
        String nameToAdd="Chris P. Bacon";
        WSIFAddress addressToAdd = 
            new WSIFAddress (1, 
                "The Waterfront",
                "Some City",
                "NY",
                47907,
                new WSIFPhone (765, "494", "4900"));

        //Jetzt werden Name und Adresse zur Eingabenachricht hinzugefügt.
        inputMessage.setObjectPart("name", nameToAdd);
        inputMessage.setObjectPart("address", addressToAdd);

        //Jetzt wird die Operation ausgeführt und eine Markierung zur erfolgreichen Ausführung empfangen.
        boolean operationSucceeded =
            operation.executeRequestResponseOperation(
                inputMessage,
                outputMessage,
                faultMessage);

        if (operationSucceeded) {
            System.out.println("Name und Adresse wurden zum Adressbuch hinzugefügt\n");
        } else {
            System.out.println("Name und Adresse konnten nicht zum Adressbuch hinzugefügt werden");
        }

        // Erneuter Beginn
        operation = null;
        inputMessage = null;
        outputMessage = null;
        faultMessage = null;

        // Jetzt wird im Adressbuch nach einer Adresse gesucht.
        // Die Operation getAddressFromName ist in der wsdl nicht überladen,
        // so dass einfach der Name der Operation ohne die Namen von Ein- oder
        // Ausgabenachrichten angegeben werden kann.
        operation = port.createOperation("getAddressFromName");

        //Die Nachrichten werden erstellt.
        inputMessage = operation.createInputMessage();
        outputMessage = operation.createOutputMessage();
        faultMessage = operation.createFaultMessage();

        //Der im Adressbuch zu suchende Name wird angegeben.
        String nameToLookup="Chris P. Bacon";
        inputMessage.setObjectPart("name", nameToLookup);

        // Die Operation wird ausgeführt.
        operationSucceeded =
            operation.executeRequestResponseOperation(
                inputMessage,
                outputMessage,
                faultMessage);

        if (operationSucceeded) {
            System.out.println("Erfolgreiche Suche nach dem Namen '"+nameToLookup+"' im Adressbuch");

            // Die gefundene Adresse kann durch Abfragen der Ausgabenachricht abgerufen werden.
            WSIFAddress addressFound = (WSIFAddress) outputMessage.getObjectPart("address");
            System.out.println("Folgende Adresse wurde gefunden:");
            System.out.println(addressFound);
        } else {
            System.out.println("Der Name wurde nicht im Adressbuch gefunden");
        }

    } catch (Exception e)  {
        System.out.println("Beim Ausführen des Beispiels ist eine Ausnahme eingetreten:");
        e.printStackTrace();
    }
}

Der obige Code bezieht sich auf die folgende Beispielmethode:

    WSIFPort getPortFromAvailablePortNames(WSIFService service)
            throws WSIFException {
        String portChosen = null;
        
        // Es wird eine Liste der für den Service verfügbaren Portnamen abgerufen.
        Iterator it = service.getAvailablePortNames();
        {
            System.out.println("Für den Service sind folgende Ports verfügbar: ");
            while (it.hasNext()) {
                String nextPort = (String) it.next();
                if (portChosen == null)
                    portChosen = nextPort;
                System.out.println(" - " + nextPort);
            }
        }
        if (portChosen == null) {
            throw new WSIFException("Keine Ports für den Service gefunden!");
        }
        System.out.println("Verwendet wird Port " + portChosen + "\n");
        
        // Alternativ kann der Port für den Service auch mit der Methode
        // setPreferredPort angegeben werden. Nachdem für den Service ein
        // bevorzugter Port definiert wurde, kann mit getPort (ohne Argumente)
        // ein WSIFPort abgerufen werden. Wenn kein bevorzugter Port definiert
        // wurde und mehr als ein Port für den im WSIFService angegebenen Porttyp
        // verfügbar ist, wird eine Ausnahme ausgelöst. 
                service.setPreferredPort(portChosen);
        WSIFPort port = service.getPort();
        return port;
    }

Der Web-Service verwendet die folgenden Klassen:

WSIFAddress:

public class WSIFAddress implements Serializable {

    //Instanzvariablen
    private int	streetNum;
    private java.lang.String	streetName;
    private java.lang.String	city;
    private java.lang.String	state;
    private int	zip;
    private WSIFPhone	phoneNumber;

    //Konstruktoren
    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 {

    //Instanzvariablen
    private int	areaCode;
    private java.lang.String	exchange;
    private java.lang.String	number;

    //Konstruktoren
    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("Das Namensargument darf nicht " +
                                               "null sein.");
        }
        return (WSIFAddress)name2AddressTable.get(name);
    }

}

Der folgende Code entspricht der WSDL-Datei für den 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://myServer/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>

Symbol, das den Typ des Artikels anzeigt. Taskartikel



Symbol für Zeitmarke Letzte Aktualisierung: 25.05.2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twsf_devwes
Dateiname:twsf_devwes.html