ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebLogic Server JAX-WS Webサービスの高度な機能のプログラミング
11g リリース1(10.3.3)
B61633-01
  目次へ移動
目次

前
 
次
 

2 非同期のリクエストとレスポンスを使用したWebサービスの呼出し

次の項では、非同期のリクエストとレスポンスを使用してWebサービスを呼び出す方法について説明します。

非同期のリクエストとレスポンス機能の概要

Webサービスを同期的に呼び出す場合、呼出し側のクライアント・アプリケーションは、レスポンスが戻るまで待機してから、処理を続行します。レスポンスが即座に戻る場合は、このWebサービス呼出しの方法が一般的です。しかし、リクエストの処理が遅延する可能性があるため、クライアント・アプリケーションによる処理を続行しレスポンスへの対処は後で行うようにする、すなわち、WebLogic Webサービスにおける非同期のリクエストとレスポンス機能を使用すると便利なことがよくあります。

クライアントに非同期のリクエストとレスポンスを実装するには、オペレーションを直接呼び出すのではなく、非同期的な種類の同じオペレーションを呼び出します。(この非同期的な種類のオペレーションは、clientgen Antタスクによって自動生成されます。)たとえば、addNumbersというオペレーションを直接呼び出すのではなく、addNumbersAsyncを呼び出します。非同期的な種類のオペレーションは、オリジナルのオペレーションが値を戻す場合でも、常にvoidを戻します。そのため、クライアントには、非同期のレスポンスまたは障害が後で戻されたときにそれを処理するメソッドを組み込みます。これらのメソッド内には、Webサービスのオペレーション呼出しに対する戻り値、または潜在的な障害を処理するビジネス・ロジックを置きます。

非同期のリクエストとレスポンスの使用:主な手順

次の手順では、Webサービス内のオペレーションを非同期的に呼び出すクライアントの作成方法を説明します。わかりやすくするために、この手順では次のことを想定しています。

さらには、Antベースの開発環境を設定済であり、かつjwsc Antタスクを実行して生成されたサービスをデプロイするためのターゲットを追加できる、作業用のbuild.xmlファイルがあることが前提となっています。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』の次の項を参照してください。

表2-1 非同期のリクエストとレスポンスを使用する手順

#
手順 説明

1

非同期メソッドの作成を可能にするため、外部バインディング宣言ファイルを作成します。

「WSDLに対する非同期バインディング宣言の適用」を参照してください。

2

非同期クライアントをコンパイルするため、build.xmlファイルを更新します。

clientgen Antタスクに外部バインディング宣言ファイルを渡すことで、非同期的な種類のWebサービス・オペレーションが自動的に生成されます。「非同期のリクエストとレスポンスを使用する場合のbuild.xmlファイルの更新」を参照してください。

3

非同期クライアントを作成します。

クライアント内で、コールバック通知を取得するための非同期コールバック・ハンドラを定義し、非同期的な種類のWebサービス・メソッドを呼び出してハンドルを非同期コールバック・ハンドラに渡します。使い慣れたIDEまたはテキスト・エディタを使用します。「非同期クライアントの作成」を参照してください。

3

Antターゲットを実行してAsyncClientをビルドします。

例:

prompt> ant build-client

WSDLに対する非同期バインディング宣言の適用

WSDLのコンパイル時に、サービス・エンド・ポイント・インタフェースで非同期のポーリング・メソッドとコールバック・メソッドを生成するには、WSDLファイルでjaxws:enableAsyncMappingバインディング宣言ファイルを有効にします。

特定のWSDLまたはXMLスキーマ・ドキュメントのすべてのバインディング宣言を格納する外部バインディング宣言ファイルを作成できます。次に、バインディング宣言ファイルをwsdlcjwsc、またはclientgen Antタスクの<binding>子要素に渡します。

次に示すバインディング宣言ファイルのサンプルでは、jaxws:enableAsyncMappingバインディング宣言を有効にしています。

<bindings
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    wsdlLocation="AddNumbers.wsdl"
    xmlns="http://java.sun.com/xml/ns/jaxws">
    <bindings node="wsdl:definitions">
        <package name="examples.webservices.async"/>
        <enableAsyncMapping>true</enableAsyncMapping>
    </bindings>
</bindings>

詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のJAX-WSバインディング宣言を使用した外部バインディング宣言ファイルの作成に関する項を参照してください。

非同期のリクエストとレスポンスを使用する場合のbuild.xmlファイルの更新

build.xmlファイルを更新して、クライアント・アーティファクトの生成と、Webサービスのオペレーションを非同期的に呼び出すクライアントのコンパイルが行われるようにするには、非同期バインディング宣言が記述された外部バインディング宣言ファイルへの参照を含むtaskdefsおよびbuild-clientターゲットを追加します。詳細は、サンプルの後の説明を参照してください。

<taskdef name="clientgen"
    classname="weblogic.wsee.tools.anttasks.ClientGenTask" />

<target name="build_client">

<clientgen
      type="JAXWS"
      wsdl="AddNumbers.wsdl"
      destDir="${clientclasses.dir}"
      packageName="examples.webservices.async.client">
      <binding file="jaxws-binding.xml" />
    </clientgen>
    <javac
      srcdir="${clientclass-dir}" destdir="${clientclass-dir}"
      includes="**/*.java"/>
    <javac
      srcdir="src" destdir="${clientclass-dir}"
      includes="examples/webservices/hello_world/client/**/*.java"/>

</target>

clientgen Antタスクの完全なクラス名を定義するには、taskdef Antタスクを使用します。「WSDLに対する非同期バインディング宣言の適用」の説明に従って外部バインディング宣言ファイルを指定することで、非同期バインディング宣言を適用します。この場合は、clientgen Antタスクによって、同期的な種類と非同期的な種類のWebサービス・オペレーションがJAX-WSスタブ内に生成されます。

非同期クライアントの作成

次に示すサンプル・クライアント・ファイルAsyncClientには、AddNumbersServiceサービスのAddNumbersAsyncメソッドを非同期的に呼び出すAddNumbersTestDriveというメソッドが定義されています。太字で示したJavaコードについては後ほど説明します。

package examples.webservices.async.client;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import javax.xml.ws.BindingProvider;

import java.util.concurrent.Future;
import javax.xml.ws.AsyncHandler; 
import javax.xml.ws.Response;

public class AsyncClient  {

   private AddNumbersPortType port = null;
   protected void setUp() throws Exception {
      AddNumbersService service = new AddNumbersService();
      port = service.getAddNumbersPort(); 
      String serverURI = System.getProperty("wls-server");
      ((BindingProvider) port).getRequestContext().put(
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
             "http://" + serverURI + "/JAXWS_ASYNC/AddNumbersService");
   }

/**
* 
* Asynchronous callback handler
*/
   class AddNumbersCallbackHandler implements AsyncHandler<AddNumbersResponse> {
      private AddNumbersResponse output;
      public void handleResponse(Response<AddNumbersResponse> response) {
         try {
            output = response.get();
         } catch (ExecutionException e) {
             e.printStackTrace();
         } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }
      AddNumbersResponse getResponse() {
         return output;
      }
   }

   public void AddNumbersTestDrive() throws Exception {
      int number1 = 10;
      int number2 = 20;
      AddNumbersCallbackHandler callbackHandler = 
         new AddNumbersCallbackHandler();
      Future<?> resp = port.addNumbersAsync(number1, number2,
         callbackHandler);
      // For the purposes of a test, block until the async call completes
      resp.get(5L, TimeUnit.MINUTES); 
int result = callbackHandler.getResponse().getReturn(); 
   }
}

非同期クライアント・ファイルを作成する際は、以下のタスクを実行する必要があります。

  1. javax.xml.ws.AsyncHandler<T>インタフェースを実装する非同期ハンドラを作成します。(http://java.sun.com/javase/6/docs/api/javax/xml/ws/AsyncHandler.htmlを参照)。この非同期ハンドラには、handleResponseメソッドを定義します。このメソッドにより、非同期的に呼び出されるサービス・エンド・ポイント・オペレーションの完了時に、クライアントがコールバック通知を受信することが可能になります。タイプはAddNumberResponseに設定する必要があります。

    class AddNumbersCallbackHandler implements AsyncHandler<AddNumbersResponse> {
       private AddNumbersResponse output;
    
       public void handleResponse(Response<AddNumbersResponse> response) {
          try {
             output = response.get();
             } catch (ExecutionException e) {
               e.printStackTrace();
             } catch (InterruptedException e) {
               e.printStackTrace();
    
             }
          }
    
          AddNumbersResponse getResponse() {
             return output;
       }
    }
    
  2. 非同期コールバック・ハンドラをインスタンス化します。

    AddNumbersCallbackHandler callbackHandler = 
       new AddNumbersCallbackHandler();
    
  3. AddNumbersService Webサービスをインスタンス化し、非同期バージョンのWebサービス・メソッドaddNumbersAsyncを呼び出して非同期コールバック・ハンドラにハンドルを渡します。

    AddNumbersService service = new AddNumbersService();
    port = service.getAddNumbersPort();
    ...
    
    Future<?> resp = port.addNumbersAsync(number1, number2,
       callbackHandler);
    

    java.util.concurrent.Futureは、(http://java.sun.com/javase/6/docs/api/java/util/concurrent/Future.htmlを参照。)非同期計算の結果を表現し、非同期タスクのステータスの確認、結果の取得、タスクの実行のキャンセルを可能にします。

  4. 非同期計算の結果を取得します。このサンプルでは、計算の完了を待機するためのタイムアウト値を指定しています。

    resp.get(5L, TimeUnit.MINUTES);
    
  5. コールバック・ハンドラを使用してレスポンス・メッセージにアクセスします。

    int result = callbackHandler.getResponse().getReturn();