WSIF サービスの開発

Web Services Invocation Framework (WSIF) サービスは、WSIF を使用する Web サービスです。

このタスクについて

WSIF サービスを開発するには、まず Web サービスを開発 (または既存の Web サービスを使用) し、次にその Web サービスを記述する Web サービス記述言語 (WSDL) 文書に基づいて WSIF クライアントを開発します。

作成済みの次の 2 つの WSIF サンプルを developerWorks® Web サイトの WebSphere® Application Server サンプル・ページからダウンロードすることもできます。

  • Address Book サンプル。
  • Stock Quote サンプル。

作成済みサンプルの使用方法について詳しくは、 developerWorks のダウンロード・パッケージに含まれている資料を参照してください。 これらのサンプルは、WebSphere Application Server バージョン 5 で動作するように作成されていることに注意してください。

WSIF サービスを開発するには、以下のステップを実行します。

手順

  1. Web サービスを実装します

    Web サービス・ツールを使用して、Web サービスの検出、作成、および公開を行います。Java Bean、エンタープライズ Bean、および URL Web サービスを開発することができます。Web サービス・ツールを使用して、WSDL 文書からスケルトン Java コードとサンプル・アプリケーションを作成できます。例えば、Enterprise Bean は、RMI-IIOP (Remote Method Invocation over Internet Inter-ORB Protocol) をアクセス・プロトコルとして使用して、Web サービスとして提供することができます。 あるいは、アクセス・プロトコルとしてネイティブの Java 呼び出しを用いて、Java クラスを Web サービスとして使用することができます。

    [AIX Solaris HP-UX Linux Windows][z/OS]StockQuote サービス・チュートリアルに示されているように、WebSphere Studio Application Developer を使用して、Java アプリケーションから Web サービスを作成できます。このシナリオで使用する Java アプリケーションは、銘柄シンボルが与えられると、最新の取引価格をインターネット Web サイト www.xmltoday.com から戻します。Web サービス・ウィザードを使用して、StockQuoteService.java Bean から、StockQuoteService-binding.wsdl という名前のバインディング WSDL 文書、および StockQuoteService-service.wsdl という名前のサービス WSDL 文書を生成します。次に、Web サービスを Web サーバーにデプロイし、Web サービスに対するクライアント・プロキシーを生成し、このクライアント・プロキシーを介して StockQuoteService にアクセスするサンプル・アプリケーションを生成します。StockQuote Web サービスをテストし、IBM® UDDI Explorer を使用して公開し、IBM UDDI Test Registry 内で StockQuote Web サービスを検出します。

    [IBM i]WebSphere Development Studio for System i® (WDS) を使用して、Java アプリケーションから Web サービスを作成できます。Web サービス・ウィザードを使用して、Java Bean からバインディング WSDL 文書とサービス WSDL 文書を生成します。次に、Web サービスを Web サーバーにデプロイし、Web サービスに対するクライアント・プロキシーを生成し、このクライアント・プロキシーを介してサービスにアクセスするサンプル・アプリケーションを生成することができます。サービスをテストし、IBM UDDI Explorer を使用して公開し、IBM UDDI Test Registry 内でそのサービスを検出します。

  2. WSIF クライアントを開発します。
    以下の情報は、WSIF クライアントの開発に役立ちます。

    AddressBook サンプルは、同期対話用に作成されています。JMS プロバイダーを使用している場合は、WSIF クライアントが非同期で動作することが必要となることがあります。 WSIF は、この要件を満たす、以下の 2 つの主なフィーチャーを提供します。

    • 相関サービス。これは、要求が、(結果として起こる) 応答に相応するように、 メッセージに ID を割り当てます。
    • 応答ハンドラー。これは、Web サービスからの応答を、あとで受け取ります。
    詳しくは、WSIFOperation - 非同期対話の解説を参照してください。

例: WSIF を使用した AddressBook サンプル Web サービスの動的呼び出し

これは、WSIF を使用して AddressBook サンプル Web サービスを動的に呼び出すコード例です。

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

        // The starting point for any dynamic invocation using wsif is a
        // WSIFServiceFactory. Create one through the newInstance
        // method.
        WSIFServiceFactory factory = WSIFServiceFactory.newInstance();

        // Once you have a factory, you can use it to create a WSIFService object
        // corresponding to the AddressBookService service in the wsdl file.
        // Note: because you only have one service defined in the wsdl file, you
        // do not have 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 in the following example 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. 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"));
            // You now have a WSIFService object. The next step is to create a WSIFPort
            // object for the port you want 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 you have a WSIFPort, you can create an operation. Execute
        // the addEntry operation and therefore attempt to create a WSIFOperation
        // corresponding to it. The addEntry operation is overloaded in the wsdl i.e. 
				// there are two versions of it, each taking different parameters (parts). 
				// This overloading requires that you specify the input and output message 
				// names for the operation in the createOperation method so that the correct 
				// operation can be resolved.
        // Because the addEntry operation has no output message, you 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 you will lookup an address from the addressbook.
        // The getAddressFromName operation is not overloaded in the
        // wsdl and therefore you can 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");

            // You can get 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();
    }
}

上記のコードは以下のサンプル・メソッドを参照します。

    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 through 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;
    }

Web サービスは以下のクラスを使用します。

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);
    }

}

次に示すコードは、対応する Web サービス用の WSDL ファイルです。

<?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>

トピックのタイプを示すアイコン タスク・トピック



タイム・スタンプ・アイコン 最終更新: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twsf_devwes
ファイル名:twsf_devwes.html