Oracle® Fusion Middleware Oracle WebLogic Server JAX-WS を使用した Web サービスの高度な機能のプログラミング 11g リリース 1 (10.3.1) B55543-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 Fusion Middleware Oracle WebLogic Server JAX-WS を使用した 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 Fusion Middleware JAX-WS を使用した Oracle WebLogic Server 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"); } /** * * 非同期コールバック ハンドラ */ 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(); } }
非同期クライアント ファイルを作成する際は、以下のタスクを実行する必要があります。
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();