Oracle® Fusion Middleware Oracle WebLogic Server JAX-WS Webサービスの高度な機能のプログラミング 11g リリース1(10.3.3) B61633-01 |
|
前 |
次 |
次の項では、非同期のリクエストとレスポンスを使用してWebサービスを呼び出す方法について説明します。
Webサービスを同期的に呼び出す場合、呼出し側のクライアント・アプリケーションは、レスポンスが戻るまで待機してから、処理を続行します。レスポンスが即座に戻る場合は、このWebサービス呼出しの方法が一般的です。しかし、リクエストの処理が遅延する可能性があるため、クライアント・アプリケーションによる処理を続行しレスポンスへの対処は後で行うようにする、すなわち、WebLogic Webサービスにおける非同期のリクエストとレスポンス機能を使用すると便利なことがよくあります。
クライアントに非同期のリクエストとレスポンスを実装するには、オペレーションを直接呼び出すのではなく、非同期的な種類の同じオペレーションを呼び出します。(この非同期的な種類のオペレーションは、clientgen
Antタスクによって自動生成されます。)たとえば、addNumbers
というオペレーションを直接呼び出すのではなく、addNumbersAsync
を呼び出します。非同期的な種類のオペレーションは、オリジナルのオペレーションが値を戻す場合でも、常にvoid
を戻します。そのため、クライアントには、非同期のレスポンスまたは障害が後で戻されたときにそれを処理するメソッドを組み込みます。これらのメソッド内には、Webサービスのオペレーション呼出しに対する戻り値、または潜在的な障害を処理するビジネス・ロジックを置きます。
次の手順では、Webサービス内のオペレーションを非同期的に呼び出すクライアントの作成方法を説明します。わかりやすくするために、この手順では次のことを想定しています。
クライアントWebサービスの名前はAsyncClient
です。
AsyncClientService
サービスは、WSDLが次のURLにある、デプロイ済みのAddNumbersService
サービスのtestEcho()
オペレーションを呼び出します。
http://localhost:7001/async/AddNumbers?WSDL
さらには、Antベースの開発環境を設定済であり、かつjwsc
Antタスクを実行して生成されたサービスをデプロイするためのターゲットを追加できる、作業用のbuild.xml
ファイルがあることが前提となっています。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』の次の項を参照してください。
使用例とサンプル
WebLogic Webサービスの開発
JWSファイルのプログラミング
Webサービスの呼出し
表2-1 非同期のリクエストとレスポンスを使用する手順
# |
手順 | 説明 |
---|---|---|
1 |
非同期メソッドの作成を可能にするため、外部バインディング宣言ファイルを作成します。 |
「WSDLに対する非同期バインディング宣言の適用」を参照してください。 |
2 |
非同期クライアントをコンパイルするため、 |
|
3 |
非同期クライアントを作成します。 |
クライアント内で、コールバック通知を取得するための非同期コールバック・ハンドラを定義し、非同期的な種類のWebサービス・メソッドを呼び出してハンドルを非同期コールバック・ハンドラに渡します。使い慣れたIDEまたはテキスト・エディタを使用します。「非同期クライアントの作成」を参照してください。 |
3 |
Antターゲットを実行して |
例: prompt> ant build-client |
WSDLのコンパイル時に、サービス・エンド・ポイント・インタフェースで非同期のポーリング・メソッドとコールバック・メソッドを生成するには、WSDLファイルでjaxws:enableAsyncMapping
バインディング宣言ファイルを有効にします。
特定のWSDLまたはXMLスキーマ・ドキュメントのすべてのバインディング宣言を格納する外部バインディング宣言ファイルを作成できます。次に、バインディング宣言ファイルをwsdlc
、jwsc
、または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
ファイルを更新して、クライアント・アーティファクトの生成と、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(); } }
非同期クライアント・ファイルを作成する際は、以下のタスクを実行する必要があります。
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; } }
非同期コールバック・ハンドラをインスタンス化します。
AddNumbersCallbackHandler callbackHandler = new AddNumbersCallbackHandler();
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
を参照。)非同期計算の結果を表現し、非同期タスクのステータスの確認、結果の取得、タスクの実行のキャンセルを可能にします。
非同期計算の結果を取得します。このサンプルでは、計算の完了を待機するためのタイムアウト値を指定しています。
resp.get(5L, TimeUnit.MINUTES);
コールバック・ハンドラを使用してレスポンス・メッセージにアクセスします。
int result = callbackHandler.getResponse().getReturn();