JAX-WS Web サービスの非同期呼び出し
Java™ API for XML-Based Web Services (JAX-WS) は、 非同期クライアント呼び出しを使用する Web サービスの呼び出しをサポートします。 JAX-WS は、Web サービスを非同期に呼び出す際に、コールバック・モデルとポーリング・モデルの両方をサポートします。コールバック・モデルとポーリング・モデルの両方は、ディスパッチ・クライアントと動的プロキシー・クライアントで使用することができます。
始める前に
JAX-WS 動的プロキシーまたはディスパッチ・クライアントを開発します。 動的プロキシー・クライアントを開発していて、wsimport コマンドを使用して Web サービス記述言語 (WSDL) ファイルから移植可能なクライアント成果物を生成した場合、生成されたサービス・エンドポイント・インターフェースには非同期メソッドが含まれていません。 JAX-WS バインディングを使用して、非同期コールバック・メソッドまたはポーリング・メソッドを動的プロキシー・クライアントのインターフェースに追加します。 非同期マッピングを使用可能にするには、 jaxws:enableAsyncMapping バインディング宣言を WSDL ファイルに追加します。 非同期インターフェースを生成するためにバインディングのカスタマイズを追加する方法について詳しくは、 JAX-WS 仕様の第 8 章を参照してください。

このタスクについて
Web サービスの非同期呼び出しは、要求をサービス・エンドポイントに送信し、応答がサービスから戻るのを待つことなく、直ちに制御をクライアント・プログラムに返します。JAX-WS 非同期 Web サービス・クライアントは、コールバック・アプローチまたは ポーリング・アプローチのいずれかを使用して Web サービスを利用します。 ポーリング・モデルを使用することにより、クライアントは、要求を発行して応答オブジェクトを受信し、それをポーリングして、サーバーが応答したかどうかを判別することができます。 サーバーが応答した場合、実際の応答が取得されます。 コールバック・モデルを使用して、クライアントはインバウンド応答オブジェクトの受信と処理を行うためのコールバック・ハンドラーを提供します。 ハンドラーの handleResponse() メソッドは、 結果が使用可能になると呼び出されます。 ポーリング・モデルとコールバック・モデルのどちらも、応答が戻るのを待たずにクライアントが処理を継続することを可能にし、Web サービスを呼び出すためのより動的で効率のよいモデルを提供できます。 ポーリング呼び出しは、Enterprise JavaBeans (EJB) クライアントから行った場合にも、 Java Platform, Enterprise Edition (Java EE) アプリケーション・クライアントから行った場合にも有効です。 コールバック呼び出しは、Java EE アプリケーション・クライアントから行う場合にのみ有効です。
- コールバック非同期呼び出しモデルの使用
- コールバック・モデルを使用する非同期呼び出しを実装する場合、 クライアントは、インバウンド応答オブジェクトを受け取って処理するための AsyncHandler コールバック・ハンドラーを提供します。 クライアントのコールバック・ハンドラーは、javax.xml.ws.AsyncHandler インターフェースを実装します。 これには、サーバーから非同期応答を受信するときに実行されるアプリケーション・コードが含まれています。 javax.xml.ws.AsyncHandler インターフェースには、 handleResponse(java.xml.ws.Response) メソッドが含まれています。 このメソッドは、ランタイムがサーバーからの非同期応答を受信して処理した後で呼び出されます。 応答は、javax.xml.ws.Response オブジェクトの形式でコールバック・ハンドラーに送信されます。応答オブジェクトは、get() メソッドが呼び出されるときに、応答コンテンツを返します。 加えて、エラーが受信された場合、その呼び出し中に例外がクライアントに戻されます。 その場合、応答メソッドは、クライアントの java.xml.ws.Service インスタンスで、実行プログラム・スレッド java.util.concurrent.Executor が使用するスレッド化モデルにより呼び出されます。java.xml.ws.Service インスタンスは、 動的プロキシーまたはディスパッチ・クライアント・インスタンスの作成に使用されたものです。 実行プログラムは、アプリケーションによって登録されたすべての非同期コールバックの呼び出しに使用されます。 setExecutor メソッドと getExecutor メソッドを使用して、 サービス用に構成された実行プログラムを変更および取得します。
- ポーリング非同期呼び出しモデルの使用
- ポーリング・モデルを使用することにより、クライアントは、要求を発行して応答オブジェクトを受信し、その後でそれをポーリングして、サーバーが応答したかどうかを判別することができます。 サーバーが応答すると、実際の応答が取得できます。 応答オブジェクトは、get() メソッドが呼び出されるときに、応答コンテンツを返します。 クライアントは、javax.xml.ws.Response というタイプのオブジェクトを invokeAsync メソッドから受信します。 その応答オブジェクトは、サーバーに対する要求の状況をモニターして、 操作の完了時刻を測定し、応答結果を取得するために使用されます。
- 非同期メッセージ交換の使用
- デフォルトでは、非同期クライアント呼び出しは、通信線上でメッセージ交換パターンの非同期動作を行いません。 プログラミング・モデルは非同期ですが、要求または応答メッセージのサーバーとの交換は非同期ではありません。 非同期メッセージ交換を使用するために、 com.ibm.websphere.webservices.use.async.mep プロパティーは、 true というブール値を指定して、クライアント要求コンテキストに従って設定する必要があります。 このプロパティーが使用可能になっている場合、クライアントとサーバーの間で交換されるメッセージは、 同期して交換されるメッセージとは異なっています。非同期交換では、 要求および応答メッセージは、それらのメッセージに追加ルーティング情報を与える WS-Addressing ヘッダーが追加されています。 非同期メッセージ交換が同期メッセージ交換と大きく異なる点として、このほかに、 応答が非同期リスナーに送信され、非同期リスナーがその応答をクライアントに送信することがあげられます。 非同期交換では、応答の listen を止めることをクライアントに通知するためにタイムアウトが送信されることはありません。 クライアントに応答待ちを止めさせるには、 ポーリング呼び出しから戻るオブジェクトで Response.cancel() メソッドを発行するか、または コールバック呼び出しから戻るオブジェクトで Future.cancel() メソッドを発行します。 取り消し応答は、要求を処理しているときはサーバーに影響を与えません。

<soapenv:Header>
<wsa:To>http://target.bar.com:81/LiteSecurityService/SecurityService</wsa:To>
<wsa:ReplyTo>
<wsa:Address>http://myhost:2146/axis2/services/LiteSecurityService.
WSRMServicePort/AnonOutInOp?IBMwebservicesID=922A5DC38A337C4CEF1168347862705
</wsa:Address>
</wsa:ReplyTo>
<wsa:MessageID>urn:uuid:922A5DC38A337C4CEF1168347862403</wsa:MessageID>
<wsa:Action>getEndpointReference</wsa:Action>
</soapenv:Header>
この問題を解決するには、以下のシステム・プロパティーを
Java 仮想マシンに追加することによって、
非同期リスナーのロケーション詳細が IP フォーマットで送信されるようにクライアントを構成します。IP アドレスを送信することによって、DHCP の利点を失うことに注意してください。-Dcom.ibm.websphere.webservices.transportEPRInIPAddr=yes
gotcha手順
タスクの結果
例
@WebService
public interface CreditRatingService {
// Synchronous operation.
Score getCreditScore(Customer customer);
// Asynchronous operation with polling.
Response<Score> getCreditScoreAsync(Customer customer);
// Asynchronous operation with callback.
Future<?> getQuoteAsync(Customer customer,
AsyncHandler<Score> handler);
}
- コールバック・メソッドの使用
- コールバック・メソッドは、 次の例に示されるコールバック・ハンドラーを必要とします。 コールバック・プロシージャーを使用する場合、 要求が行われた後は、コールバック・ハンドラーがその応答の処理を担当します。 応答の値は、応答、またはおそらく例外です。 Future<?> メソッドは、非同期計算の結果を表し、 計算が完了しているかどうかを確認するためにチェックされます。 アプリケーションに要求が完了しているかどうかを確認させる場合は、 Future.isDone() メソッドを呼び出します。 Future.get() メソッドは有意義な応答をせず、 Response.get() メソッドとは似ていないことに注意してください。
CreditRatingService svc = ...;
Future<?> invocation = svc.getCreditScoreAsync(customerTom,
new AsyncHandler<Score>() {
public void handleResponse (
Response<Score> response)
{
score = response.get();
// process the request...
}
}
);
- ポーリング・メソッドの使用
- 以下の例は、 非同期ポーリング・クライアントを示しています。
CreditRatingService svc = ...;
Response<Score> response = svc.getCreditScoreAsync(customerTom);
while (!response.isDone()) {
// Do something while we wait.
}
score = response.get();