![]() ![]() ![]() ![]() |
以下の節では、非同期の要求と応答を使用して Web サービスを呼び出す方法について説明します。
Web サービスを同期的に呼び出す場合、呼び出し側のクライアント アプリケーションは、応答が返るまで待機してから、処理を続行します。応答が即座に返る場合、この Web サービス呼び出しの方法は一般的です。しかし、要求の処理が遅延する可能性があるため、クライアント アプリケーションによる処理を続行し応答への対処は後で行うようにする、すなわち、WebLogic Web サービスにおける非同期の要求と応答機能を使用すると便利なことがよくあります。
クライアントで非同期の要求と応答を実装するには、オペレーションを直接呼び出すよりも、非同期的な種類の同じオペレーションを呼び出します (この非同期的な種類のオペレーションは、clientgen
Ant タスクによって自動生成されます)。たとえば、addNumbers
というオペレーションを直接呼び出すのではなく、addNumbersAsync
を呼び出します。非同期的な種類のオペレーションは、オリジナルのオペレーションが値を返す場合でも、常に void
を返します。その後クライアントに、非同期の応答を処理するメソッド、または後で応答が返る場合はエラーを格納します。これらのメソッド内には、Web サービスのオペレーション呼び出しに対する戻り値、または潜在的なエラーを処理する、すべてのビジネス ロジックを置きます。
次の手順では、Web サービス内のオペレーションを非同期的に呼び出すクライアントの作成方法を説明します。分かりやすくするために、この手順では以下を想定しています。
さらには、Ant ベースの開発環境を設定済みであり、かつ jwsc
Ant タスクを実行して、生成されたサービスをデプロイするためのターゲットを追加できる、作業用の build.xml
ファイルがあることが前提となっています。詳細については、『JAX-WS を使用した WebLogic Web サービスの開始』の以下の節を参照してください。
clientgen Ant タスクに外部バインディング宣言ファイルを渡すことで、非同期的な種類の Web サービス オペレーションが自動的に生成されます。「非同期の要求と応答を使用する場合の build.xml ファイルの更新」を参照してください。
|
||
prompt> ant build-client |
次に示すサンプル クライアント ファイル 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>
インタフェースを実装する非同期ハンドラを作成します。この非同期ハンドラには、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
は、非同期計算の結果を表現し、非同期タスクのステータスの確認、結果の取得、タスクの実行のキャンセルを可能にします。
resp.get(5L, TimeUnit.MINUTES);
int result = callbackHandler.getResponse().getReturn();
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>
詳細については、『JAX-WS を使用した WebLogic 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 スタブ内に生成されます。
![]() ![]() ![]() |