40.5. コールバックアプローチを使用した非同期クライアントの実装

概要

非同期操作の呼び出しを行う別のアプローチは、コールバッククラスを実装することです。次に、コールバックオブジェクトをパラメーターとして受け取る非同期リモートメソッドを呼び出します。ランタイムは、コールバックオブジェクトへの応答を返します。

コールバックを使用するアプリケーションを実装するには、次のようにします。

  1. AsyncHandler インターフェイスを実装するコールバッククラスを 作成 します。

    注記

    コールバックオブジェクトは、アプリケーションに必要な任意の量の応答処理を実行できます。

  2. コールバックオブジェクトをパラメーターとして取り Future<?> オブジェクトを返す operationNameAsync() を使用して、リモート呼び出しを行います。
  3. クライアントが応答データにアクセスする必要がある場合は、返された Future<?> オブジェクトの isDone() メソッドをポーリングして、リモートエンドポイントが応答を送信しているかどうかを確認できます。

    コールバックオブジェクトがすべての応答処理を実行する場合、応答が到着したかどうかを確認する必要はありません。

コールバックの実装

コールバッククラスは、javax.xml.ws.AsyncHandler インターフェイスを実装する必要があります。インターフェイスは単一のメソッド handleResponseResponse<T>res を定義します。Apache CXF ランタイムは handleResponse() メソッドを呼び出して、レスポンスが到達していることをクライアントに通知します。例40.8「javax.xml.ws.AsyncHandler インターフェイス」 は、実装する必要のある AsyncHandler インターフェイスの概要を示しています。

例40.8 javax.xml.ws.AsyncHandler インターフェイス

public interface javax.xml.ws.AsyncHandler
{
  void handleResponse(Response<T> res)
}

例40.9「コールバックの実装クラス」 は、例40.1「非同期の例の WSDL コントラクト」 で定義された greetMeSometime 操作のコールバッククラスを示しています。

例40.9 コールバックの実装クラス

package demo.hw.client;

import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;

import org.apache.hello_world_async_soap_http.types.*;

public class GreeterAsyncHandler implements AsyncHandler<GreetMeSometimeResponse>
{
  private GreetMeSometimeResponse reply;

  public void handleResponse(Response<GreetMeSometimeResponse>
                             response)
  {
    try
    {
      reply = response.get();
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
  }

  public String getResponse()
  {
    return reply.getResponseType();
  }
}

例40.9「コールバックの実装クラス」 に示すコールバックの実装は次のことを行います。

リモートエンドポイントから返される応答を保持するメンバー変数 response を定義する。

handleResponse() を実装する。

この実装は、応答を抽出してそれをメンバー変数 reply に割り当てるだけです。

getResponse() という追加メソッドを実装する。

このメソッドは、reply からデータを抽出して返す便利な方法です。

コンシューマーの実装

例40.10「非同期操作コールのコールバックアプローチ」 は、コールバックアプローチを使用して、例40.1「非同期の例の WSDL コントラクト」 で定義された GreetMeSometime 操作への非同期呼び出しを行うクライアントを示しています。

例40.10 非同期操作コールのコールバックアプローチ

package demo.hw.client;

import java.io.File;
import java.util.concurrent.Future;

import javax.xml.namespace.QName;
import javax.xml.ws.Response;

import org.apache.hello_world_async_soap_http.*;

public final class Client {
  ...

  public static void main(String args[]) throws Exception
  {
    ...
    // Callback approach
    GreeterAsyncHandler callback = new GreeterAsyncHandler();

    Future<?> response =
      port.greetMeSometimeAsync(System.getProperty("user.name"),
                                callback);
    while (!response.isDone())
    {
      // Do some work
    }
    resp = callback.getResponse();
    ...
    System.exit(0);
  }
}

例40.10「非同期操作コールのコールバックアプローチ」 のコードは、以下を行います。

コールバックオブジェクトをインスタンス化します。

プロキシーのコールバックオブジェクトを取得する greetMeSometimeAsync() を呼び出す。

メソッド呼び出しは、Future<?> オブジェクトを即座にクライアントに返します。Apache CXF ランタイムは、リモートエンドポイントからの応答受信、コールバックオブジェクトの handleResponse() メソッド呼び出し、および Response<GreetMeSometimeResponse> オブジェクト反映の詳細を処理します。

注記

ランタイムはリクエストをリモートエンドポイントの greetMeSometime() メソッドに送信し、呼び出しの非同期性の詳細をリモートエンドポイントが認識することなく処理します。エンドポイント、したがってサービス実装は、クライアントが応答を待機する方法の詳細について心配する必要はありません。

返された Future<?> オブジェクトの isDone() メソッドを使用して、応答がリモートエンドポイントから到達しているかどうかを確認する。

コールバックオブジェクトの getResponse() メソッドを呼び出し、応答データを取得する。