ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebLogic Server JAX-WS を使用した Web サービスの高度な機能のプログラミング
11g リリース 1 (10.3.1)
B55543-01
  目次
目次

戻る
戻る
 
次へ
次へ
 

2 非同期の要求と応答を使用した Web サービスの呼び出し

以下の節では、非同期の要求と応答を使用して Web サービスを呼び出す方法について説明します。

非同期の要求と応答機能の概要

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

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

非同期の要求と応答の使用 : 主な手順

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

さらには、Ant ベースの開発環境を設定済みであり、かつ jwsc Ant タスクを実行して、生成されたサービスをデプロイするためのターゲットを追加できる、作業用の build.xml ファイルがあることが前提となっています。詳細については、以下の『Oracle Fusion Middleware 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 Fusion Middleware JAX-WS を使用した Oracle WebLogic Server 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");
   }

/**
* 
* 非同期コールバック ハンドラ
*/
   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);
      // テストのために、非同期コールを完了するまでブロックします。
      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();