Oracle® Fusion Middleware Oracle WebLogic Server JAX-WS Webサービスの高度な機能のプログラミング 12cリリース1(12.1.1) B65943-02 |
|
前 |
次 |
この章では、Java API for XML Web Services(JAX-WS)を使用したWebLogic Webサービスを非同期に呼び出す方法について説明します。
この章の内容は以下のとおりです。
Webサービスの非同期呼出しをサポートするため、WebLogic Webサービスでは、非同期クライアント・プログラミング・モデルと非同期トランスポートのどちらか一方または両方を使用できます。
表4-1では、非同期クライアント・プログラミング・モデルの主要な利点とトランスポート・タイプ、およびWebサービスの非同期呼出しをサポートするために使用できる構成オプションについて説明します。
注意: 2つのportType(非同期操作用に1つとコールバック操作用に1つ)として定義される2つの一方向操作を含む非同期Webサービス用のWSDLを生成する方法は、現在のリリースではサポートされていません。 |
表4-1 非同期Webサービス呼出しのサポート
タイプ | 説明 | 利点 |
---|---|---|
クライアント・プログラミング・モデル |
Webサービス操作の呼出しに使用される呼出しセマンティクスを記述します(同期または非同期)。 Webサービスを同期的に呼び出す場合、呼出し側のクライアント・アプリケーションは、レスポンスが戻るまで待機してから、処理を続行します。レスポンスが即座に戻る場合であれば、このWebサービス呼出しの方法は適切であると考えられます。しかし、リクエストの処理が遅延する可能性があるため、クライアント・アプリケーションによる処理を続行しレスポンスへの対処は後で行うようにすると便利なことがよくあります。 Webサービスを非同期的に呼び出すと、クライアントは処理を中断することなく続行でき、非同期レスポンスが返ると通知を受け取ります。 非同期呼出しをサポートするには、 |
非同期的に呼び出すことで、Webサービス・クライアントは、Webサービスに対するリクエストを開始し、中断することなく処理を続行し、以降の何らかの時点でレスポンスを受け取ることができます。 |
トランスポート |
トランスポートには、非同期クライアント・トランスポート、接続作成トランスポート、同期トランスポートの3種類があります。トランスポートの各タイプの比較については、表4-2を参照してください。 |
非同期クライアント・トランスポートおよび接続作成トランスポートの主要な利点は次のとおりです。
|
構成 |
Webサービスの非同期呼出しをサポートするようにWebサービスの永続性とバッファリング(オプション)を構成します。 詳細は、「Webサービスを非同期に呼び出すためのサーバーの構成」を参照してください。 |
Webサービス機能の構成には、次のような利点があります。
|
表4-2では、Webサービス・クライアントからのWebサービスの非同期呼出し(または、構成されている場合は同期呼出し)に対してWebLogic Serverがサポートするトランスポートのタイプを示します。
表4-2 Webサービスの非同期呼出しのトランスポート・タイプ
トランスポート・タイプ | 説明 |
---|---|
非同期クライアント・トランスポート |
アドレス可能なクライアント側非同期レスポンス・エンドポイントとWS-Addressingを使用することで、スケーラブルな非同期クライアント・プログラミング・モデルを提供します。 非同期クライアント・トランスポートは、レスポンス・メッセージの配信を、リクエスト・メッセージの送信に使用されるトランスポート・リクエストの開始から切り離します。レスポンス・メッセージは、Webサービスから開始する新しい接続を使用して、非同期レスポンス・エンドポイントに送信されます。クライアントは、WS-Addressingヘッダーを使用して、リクエスト・メッセージとレスポンス・メッセージを関連付けます。 非同期クライアント・トランスポートは、向上したフォルト・トレランスを提供し、サーバー負荷のスパイクをより適切に緩和できるようにします。 非同期クライアント・トランスポートの使用に関する詳細は、「スケーラブルな非同期JAX-WSクライアントの開発(非同期クライアント・トランスポート)」を参照してください。 非同期クライアント・トランスポートは、次のプログラミング・モデルをサポートします。
|
接続作成トランスポート |
Web Services Make Connection 1.1または1.0を使用してファイアウォールの内側からの非同期Webサービス呼出しを可能にします。 接続作成は、非同期クライアント・トランスポートの代わりとなるクライアント・ポーリング・メカニズムです。非同期クライアント・トランスポートと同様に、接続作成を使用するとリクエスト・メッセージの送信に使用されるトランスポート・リクエストの開始から、レスポンス・メッセージを切り離すことができます。ただし、レスポンスを転送するためにアドレス可能な非同期レスポンス・エンドポイントを必要とする非同期クライアント・トランスポートとは異なり、接続作成では、通常、リクエスト・メッセージの送信元はアドレス可能ではなく、着信接続を受け付けることはできません。たとえば、送信元がファイアウォールの内側にあるような場合です。 接続作成トランスポートは、向上したフォルト・トレランスを提供し、サーバー負荷のスパイクをより適切に緩和できるようにします。 接続作成トランスポートの詳細は、「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」を参照してください。 接続作成トランスポートは拡張性があり、JVMを再起動しても維持されるため、ファイアウォールの内側から非同期呼出しを使用するときのベスト・プラクティスとしてお薦めします。次のプログラミング・モデルをサポートします。
拡張性があり、JVMを再起動しても維持されるため、非同期呼出しを使用するときのベスト・プラクティスとして、接続作成トランスポートと |
同期トランスポート |
WS-Addressingの非常に制限されたサポートで、同期と非同期のWebサービス呼出しをサポートします。詳細は、「JAX-WS参照実装の使用」を参照してください。 同期呼出しを使用するときは、同期トランスポートをお薦めします。ベスト・プラクティスとはみなされませんが、非同期呼出しに使用することもできます。次のプログラミング・モデルをサポートします。
|
この項では、Webサービスを非同期に呼び出すために必要な手順について説明します。
Antベースの開発環境を設定済であり、かつjwsc
Antタスクを実行してWebサービスをデプロイするためのターゲットを追加できる、作業用のbuild.xml
ファイルがあることが前提となっています。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』を参照してください。
表4-3 非同期でWebサービスを呼び出すための手順
# |
手順 | 説明 |
---|---|---|
1 |
Webサービスの非同期呼出しをサポートするようにWebサービスの永続性を構成します。 |
Webサービスまたはクライアントでメッセージを処理するために必要なコンテキスト情報を保持するように、WebサービスとクライアントをホストするサーバーでWebサービスの永続性を構成します。詳細は、「非同期Webサービス呼出しのためのサーバーの構成」を参照してください。 注意: 「JAX-WS参照実装の使用」で説明されているように、(手順3で)標準のJAX-WS RI実装と同期トランスポートを使用してWebサービス・クライアントをプログラミングしている場合は、この手順は必要ありません。 |
2 |
Webサービス・バッファリングを構成して、リクエストを非同期的に処理するためのWebサービスを有効化します。(オプション) |
この手順はオプションです。リクエストを非同期に処理するようにWebサービスを構成するには、Webサービスをホストするサーバーでバッファリングを構成します。バッファリングを使用すると、Webサービスによる非同期処理のためにJMSキューにメッセージを格納できます。詳細は、「非同期Webサービス呼出しのためのサーバーの構成」を参照してください。 |
3 |
非同期呼出しに必要なクライアント・アーティファクトを作成します。 |
サービス・エンドポイント・インタフェースで非同期ポーリング・メソッドおよび非同期コールバック・ハンドラ・メソッドを生成するには、非同期マッピングを可能にする外部バインディング宣言を作成し、クライアントをコンパイルするときに |
4 |
必要なトランスポートとプログラミング・モデルに基づいて、Webサービス・クライアントを実装します。 |
必要なトランスポートとプログラミング・モデルに応じて、次のいずれかの項を参照してください。
クラスタでWebサービスを使用するときは、「非同期Webサービス・メッセージングのクラスタリングに関する考慮事項」で説明されているガイドラインを確認してください。 |
5 |
Webサービス・クライアントをコンパイルし、クライアント・アーティファクトのパッケージを作成します。 |
詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のクライアント・アプリケーションのコンパイルと実行に関する項を参照してください。 |
6 |
Webサービス・クライアントをデプロイします。 |
『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のWebLogic Webサービスのデプロイとアンデプロイに関する項を参照してください。 |
7 |
Webサービス・クライアントをモニターします。 |
管理コンソールまたはWLSTを使用して、呼出し、エラー、フォルトの数など、Webサービスを非同期に呼び出すクライアントの実行時情報をモニターできます。「非同期Webサービス呼出しのモニタリング」を参照してください。 |
注意: 「JAX-WS参照実装の使用」で説明されているように、標準のJAX-WS RI実装と同期トランスポートを使用してWebサービス・クライアントをプログラミングしている場合は、この手順は必要ありません。 |
Webサービスの非同期呼出しをサポートするには、Webサービスとクライアントをデプロイするサーバーで、次の表で定義されている機能を構成する必要があります。
表4-4 非同期Webサービス呼出しの構成
機能 | 説明 |
---|---|
永続性 |
Webサービスの永続性は、次の種類の情報を保存するために使用されます。
接続作成トランスポート・プロトコルは、Webサービスの永続性を次のように利用します。
構成ウィザードでWebサービス固有の拡張テンプレートを使用してWebLogic Serverドメインを拡張することにより、Webサービスの永続性を構成できます。あるいは、Oracle WebLogic管理コンソールまたはWLSTを使用して、これらの高度な機能に必要なリソースを構成できます。Webサービス永続性の構成の詳細は、「Webサービス・クライアントのためのWebサービス永続性の構成」を参照してください。クライアントとメッセージの情報の保持に使用できるAPIの詳細は、「レスポンスへのリクエスト・コンテキストの伝播」を参照してください。 |
メッセージ・バッファリング |
バッファ付き操作がクライアントによって呼び出されると、リクエストはJMSキューに格納され、WebLogic Serverはリクエストを非同期に処理します。リクエストがまだキューの中にある間にWebLogic Serverがダウンした場合は、WebLogic Serverが再起動してからすぐにリクエストの処理が行われます。メッセージ・バッファリングは、Webサービスをホストしているサーバー上で構成されます。構成情報の詳細は、第8章「Webサービスのためのメッセージ・バッファリングの構成」を参照してください。 注意: Webサービス・クライアントではメッセージ・バッファリングが自動的に有効になります。 |
WebLogic Serverのクライアント側ツール(clientgen
など)を使用すると、非同期Webサービス呼出しに必要なクライアント・アーティファクトを自動的に生成できます。具体的には、次のアーティファクトが生成されます。
リクエストごとの非同期コールバック・ハンドラを使用して、または使用しないで、Webサービスを非同期に呼び出すためのサービス・エンドポイント・インタフェース。たとえば、Webサービスで次のようなメソッドが定義されているものとします。
public int addNumbers(int opA, int opB) throws MyException
この場合は、次のようなメソッドが生成されます。
public Future<?> addNumbersAsync(int opA, int opB, AsyncHandler<AddNumbersResponse>) public Response<AddNumbersResponse> addNumbersAsync(int opA, int opB)
ハンドラを実装し、AsyncClientHandlerFeature
を使用してポート上にそのハンドラを設定するための非同期ハンドラ・インタフェース。非同期ハンドラ・インタフェースの名前は、portInterfaceName
AsyncHandler
となり、ここでportInterfaceName
はポート・インタフェース名を指定します。
たとえば、ポート・タイプ名がAddNumbersPortType
であるWebサービスの場合、次のメソッドを含むAddNumbersPortTypeAsyncHandler
という名前の非同期ハンドラ・インタフェースが生成されます。
public void onAddNumbersResponse(Response<AddNumbersResponse>)
AsyncClientHandlerFeature
については、後の「非同期ハンドラ・インタフェースの開発」で説明します。
WSDLのコンパイル時に、サービス・エンドポイント・インタフェースで非同期クライアント・アーティファクトを生成するには、WSDLファイルでjaxws:enableAsyncMapping
バインディング宣言を有効にします。
あるいは、特定のWSDLまたはXMLスキーマ・ドキュメントのすべてのバインディング宣言を格納する外部バインディング宣言ファイルを作成できます。次に、バインディング宣言ファイルをwsdlc
、jwsc
、またはclientgen
Antタスクの<binding
子要素に渡します。詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のJAX-WSバインディング宣言を使用した外部バインディング宣言ファイルの作成に関する項を参照してください。
次に示すバインディング宣言ファイル(jaxws-binding.xml
)の例では、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>
次に、build.xml
ファイルを更新し、Webサービス操作を非同期に呼び出すために必要なクライアント・アーティファクトを生成するため、次の手順を実行します。
taskdef
Antタスクを使用して、clientgen
Antタスクの完全なクラス名を定義します。
前に定義した非同期バインディング宣言が格納されている外部バインディング宣言ファイルへの参照を含むターゲットを追加します。この場合、clientgen
Antタスクは、同期的な種類と非同期的な種類のWebサービス操作をJAX-WSスタブ内に生成します。
例:
<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/async/client/**/*.java"/>
</target>
非同期クライアント・トランスポート機能は、スケーラブルな非同期クライアント・プログラミング・モデルを提供します。具体的には、次のような機能があります。
図4-1に示すような、クライアント側の非同期レスポンス・エンドポイントを公開します。
要求された非同期ハンドラの実装を呼び出すサービスの実装を作成して公開します。
すべての非一方向アウトバウンド・メッセージに、WS-Addressingの非匿名ReplyToヘッダーを自動的に追加します。このヘッダーは、公開されたレスポンス・エンドポイントを参照します。
前記の機能を使用して、非同期リクエストとレスポンス・メッセージを関連付けます。
非同期クライアント・トランスポート機能が有効になっているとき、他のすべてのJAX-WSクライアント・プログラミング・モデル(非同期ポーリング、コールバック・ハンドラ、ディスパッチなど)は引き続きサポートされます。非同期クライアント・トランスポート機能が有効になっているとき、この機能を使用するように明示的に構成されていないと、同期Webサービス操作はデフォルトで同期トランスポートを使用します。
次の図では、非同期クライアント・トランスポート機能が使用するメッセージ・フローを示します。
前の図に示すように、次のような処理が行われます。
クライアントは、クライアント・プロキシで非同期クライアント・トランスポート機能を有効にして、非同期Webサービス操作を呼び出します。
Webサービス操作がクライアント・プロキシを介して呼び出されます。
Webサービスはリクエストを処理し、(その後のどこかの時点で)レスポンス・メッセージをクライアントに返送します。レスポンス・メッセージはクライアントの非同期レスポンス・エンドポイントに送信されます。非同期レスポンス・エンドポイントのアドレスは、WS-Addressingヘッダーに保持されています。
レスポンス・メッセージがクライアント・プロキシを介して適切なクライアントに転送されます。
レスポンス・メッセージを処理するために、クライアントの非同期ハンドラが呼び出されます。
次の項では、非同期クライアント・トランスポートを使用してスケーラブルな非同期JAX-WSクライアントを開発する方法を説明します。
注意: 接続作成と非同期クライアント・トランスポート機能を一緒に使用することはできません。同じWebサービス・クライアントで両方の機能を有効にしようとすると、エラーが返されます。接続作成の詳細は、「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」を参照してください。 |
クライアントで非同期クライアント・トランスポート機能を有効にするには、Webサービス・プロキシまたはディスパッチを作成するときにパラメータとしてweblogic.jws.jaxws.client.async.AsyncClientTransportFeature
のインスタンスを渡します。次の項では、クライアントで非同期クライアント・トランスポート機能を有効にして構成する方法を説明します。
AsyncClientTransportFeature
によって記述されている非同期レスポンス・エンドポイントは、同じクライアントIDを共有するすべてのクライアント・インスタンスによって使用され、そのクライアントIDを使用する最初のクライアント・インスタンスが公開された時点から有効になります。非同期レスポンス・エンドポイントは、クライアントIDが明示的に破棄されるか、または(たとえば、ホストWebアプリケーションまたはEJBがアンデプロイされて)クライアントのコンテナが非アクティブ化されるまで、発行されたままになります。クライアントIDの管理の詳細は、『Oracle WebLogic Server JAX-WS Webサービス・スタート・ガイド』のクライアントIDの管理に関する項を参照してください。
非同期レスポンス・エンドポイント・アドレスは、次の形式を使用して自動的に生成されます。
http://contextAddress:port/context/targetPort-AsyncResponse
各値の説明は次のとおりです。
contextAddress
:
port
: 次のいずれかを指定します。
クラスタ・アプリケーションの場合は、クラスタ・アドレスとポート。
クラスタ・アプリケーションでない場合は、選択されているプロトコルのデフォルトのWebLogic Serverアドレスとポート。
デフォルトのアドレスが定義されていない場合は、指定されているプロトコルの最初のネットワーク・チャネル・アドレス。ネットワーク・チャネルの詳細は、『Oracle WebLogic Serverサーバー環境の構成』のネットワーク・リソースの構成に関する項を参照してください。
context
: 既存のコンテキスト内で実行している場合は、現在のサーブレット・コンテキスト。それ以外の場合は、UUIDによって名前を指定され、スコープがアプリケーションに設定された、新しいコンテキスト。
targetPort
-AsyncResponse
: クライアントによってアクセスされるサービスのポート名の後に-AsyncResponse
を付加したもの。
非同期クライアント・トランスポート機能は、次の項で説明するように構成できます。
AsyncClientTransportFeature()
コンストラクタの形式の詳細は、WebLogic Server Javadocを参照してください。
次に示すように、非同期レスポンス・エンドポイントのアドレスは、AsyncClientTransportFeature
に引数として渡すことで構成できます。
String responseAddress = "http://myserver.com:7001/myReliableService/myClientCallback"; AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(responseAddress); BackendService port = _service.getBackendServicePort(asyncFeature);
指定アドレスは、サーバーまたはクラスタの合法的なアドレスにする必要があります(ネットワーク・チャネルまたはプロキシ・アドレスを含む)。エフェメラル・ポートはサポートされません。指定するコンテキストは、スコープを現在のアプリケーション内に指定されているか、または未使用コンテキストを参照している必要があります。別のデプロイ済アプリケーションにスコープが設定されているコンテキストは参照できません。参照しようとするとエラーがスローされます。
次の表では、非同期レスポンス・エンドポイントのアドレスの構成に使用できるコンストラクタを示します。
表4-5 非同期レスポンス・エンドポイントのアドレスを構成するためのコンストラクタ
コンストラクタ | 説明 |
---|---|
|
非同期レスポンス・エンドポイントのアドレスを構成します。 |
|
次のものを構成します。
|
|
次のものを構成します。
|
非同期レスポンス・エンドポイントのjavax.xml.ws.wsaddressing.W3CEndpointReference
型のすべての発信ReplyToおよびFaultToヘッダーに対して使用するアドレスは、AsyncClientTransportFeature
に引数として渡すことで構成できます。
たとえば、ReplyToヘッダー・アドレスのみを構成するには次のようにします。
W3CEndpointReference replyToAddress = "http://myserver.com:7001/myReliableService/myClientCallback"; AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(replyToAddress); BackendService port = _service.getBackendServicePort(asyncFeature);
ReplyToとFaultToの両方のヘッダー・アドレスを構成するには次のようにします。
W3CEndpointReference replyToAddress = "http://myserver.com:7001/myReliableService/myClientCallback"; W3CEndpointReference faultToAddress = "http://myserver.com:7001/myReliableService/FaultTo"; AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(replyToAddress, faultToAddress); BackendService port = _service.getBackendServicePort(asyncFeature);
次の表では、発信ReplyToおよびFaultToヘッダーのエンドポイント参照アドレスの構成に使用できるコンストラクタを示します。
表4-6 ReplyToおよびFaultToヘッダーを構成するためのコンストラクタ
コンストラクタ | 説明 |
---|---|
|
発信ReplyToヘッダーのエンドポイント参照アドレスを構成します。 |
|
次のものを構成します。
|
|
次のものを構成します。
|
|
発信ReplyToおよびFaultToヘッダーのエンドポイント参照アドレスを構成します。 |
|
次のものを構成します。
|
|
次のものを構成します。
|
クライアントがサーブレットまたはWebアプリケーション・ベースのWebサービス内で実行している場合、ServletContextとコンテキスト・パスを使用して非同期レスポンス・エンドポイントを構成できます。次のように、AsyncClientTransportFeature
に引数として情報を渡します。
サーブレット内で実行している場合:
AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(getServletContext());
WebサービスまたはEJBベースのWebサービス内で実行している場合:
import com.sun.xml.ws.api.server.Container; ... Container c = ContainerResolver.getInstance().getContainer(); ServletContext servletContext = c.getSPI(ServletContext.class); AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(servletContext);
指定するコンテキストは、スコープを現在のアプリケーション内に指定されているか、または未使用コンテキストを参照している必要があります。別のデプロイ済みアプリケーションにスコープが設定されているコンテキストは参照できません。
注意:
|
次の表では、非同期レスポンス・エンドポイントのコンテキスト・パスの構成に使用できるコンストラクタを示します。
表4-7 非同期レスポンス・エンドポイントのコンテキスト・パスを構成するためのコンストラクタ
コンストラクタ | 説明 |
---|---|
|
非同期レスポンス・エンドポイントのコンテキスト・パスを構成します。 |
|
次のものを構成します。
|
次のプロパティを構成するときにdoPublish
ブール値をAsycnClientTransportFeature()
に引数として渡すことで、非同期レスポンス・エンドポイントを公開するかどうかを構成できます。
非同期レスポンス・エンドポイントのアドレス。表4-5を参照してください。
ReplyToおよびFaultToヘッダー。表4-6を参照してください。
非同期レスポンス・エンドポイントのコンテキスト・パス。表4-7を参照してください。
doPublish
をfalseに設定した場合は、非同期レスポンス・エンドポイントは自動的に発行されませんが、WS-Addressingヘッダーがアウトバウンドの非一方向メッセージに追加されます。このシナリオは次のプログラミング・モデルをサポートします。
非同期ポーリング(Responseオブジェクトへのアクセスは試みられません)
ディスパッチ非同期ポーリング(Responseオブジェクトへのアクセスは試みられません)
ディスパッチ一方向呼出し
同期トランスポート・オプションを使用する同期呼出し(デフォルト)
他のすべての非同期プログラミング・モデルについては、非同期レスポンス・エンドポイントが使用できる必要があり、doPublish
がfalseに設定されている場合は、Webサービス・クライアントはアウトバウンド・リクエストを行う前にエンドポイントを公開する必要があります。
次の例では、非同期レスポンス・エンドポイント・アドレスを構成し、非同期レスポンス・エンドポイントを公開します。
String responseAddress = "http://localhost:7001/myReliableService/myReliableResponseEndpoint"; boolean doPublish = true; AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(responseAddress, doPublish); BackendService port = _service.getBackendServicePort(asyncFeature);
次のプロパティを構成するときに、useAsyncWithSyncInvoke
ブール・フラグを使用して、同期操作用の非同期クライアント・トランスポートを有効または無効にできます。
非同期レスポンス・エンドポイントのアドレス。表4-5を参照してください。
ReplyToおよびFaultToヘッダー。表4-6を参照してください。
非同期レスポンス・エンドポイントのコンテキスト・パス。表4-7を参照してください。
次の例では、非同期レスポンス・エンドポイント・アドレスを構成し、同期操作に対して非同期クライアント・トランスポートを使用できるようにします。
String responseAddress = "http://localhost:7001/myReliableService/myReliableResponseEndpoint"; boolean useAsyncWithSyncInvoke = true; AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(responseAddress, useAsyncWithSyncInvoke); BackendService port = _service.getBackendServicePort(asyncFeature);
注意: この項で説明するように単一の非同期ハンドラ・インスタンスをポートに設定した後、「JAX-WS参照実装の使用」で説明されているようにリクエスト単位の非同期ハンドラの構成を試みると、実行時例外が返されます。 |
「Webサービスを非同期に呼び出すためのクライアント・アーティファクトの構築」で説明されているように、非同期ハンドラ・インタフェースweblogic.jws.jaxws.client.async.AsyncClientHandlerFeature
は、リクエスト単位ベースではなく、ポートに単一の非同期ハンドラ・インスタンスを設定します。
たとえば、「Webサービスを非同期に呼び出すためのクライアント・アーティファクトの構築」で説明されているようにclientgenを使用してクライアント・クラスを構築するときは、次に示すように、非同期ハンドラ・インタフェースが生成されます。
例4-1 非同期ハンドラ・インタフェースの例
import javax.xml.ws.Response; /** * This class was generated by the JAX-WS RI. * Oracle JAX-WS 2.1.5 * Generated source version: 2.1 * */ public interface BackendServiceAsyncHandler { /** * * @param response */ public void onDoSomethingResponse(Response<DoSomethingResponse> response); }
非同期ハンドラ・インタフェースは、ポート・インタフェースと同じパッケージの一部として生成され、サービスで定義されている操作に対するレスポンスを受け取るために必要なメソッドを表します。クライアントのコードでこのインタフェースをインポートして実装し、厳格に型指定された方法で非同期レスポンスを受信して処理する手段を提供できます。
ポートに単一の非同期ハンドラ・インスタンスを設定するには、Webサービス・プロキシまたはディスパッチを作成するときに、パラメータとしてweblogic.jws.jaxws.client.async.AsyncClientHandlerFeature
のインスタンスを渡します。レスポンス・メッセージを受信したときに呼び出される非同期ハンドラの名前を指定します。
次の例では、非同期ハンドラ・インタフェースの開発方法を示します。この例を見ると、AsyncClientHandlerFeature
を初期化し、バックエンド・サービスで呼出しを行うために使用されるポートに非同期ハンドラの実装を接続する方法がわかります。この例は、例3-2「非同期Webサービス・クライアントのベスト・プラクティスの例」からの抜粋です。
例4-2 非同期ハンドラ・インタフェースの開発の例
import weblogic.jws.jaxws.client.async.AsyncClientHandlerFeature; ... BackendServiceAsyncHandler handler = new BackendServiceAsyncHandler() { public void onDoSomethingResponse(Response<DoSomethingResponse> res) { // ... Handle Response ... try { DoSomethingResponse response = res.get(); _lastResponse = response.getReturn(); System.out.println("Got async response: " + _lastResponse); } catch (Exception e) { _lastResponse = e.toString(); e.printStackTrace(); } } }; AsyncClientHandlerFeature handlerFeature = new AsyncClientHandlerFeature(handler); features.add(handlerFeature); _features = features.toArray(new WebServiceFeature[features.size()]); BackendService anotherPort = _service.getBackendServicePort(_features); ... // Make the invocation. Our asynchronous handler implementation (set // into the AsyncClientHandlerFeature above) receives the response. String request = "Dance and sing"; System.out.println("Invoking DoSomething asynchronously with request: " + request); anotherPort.doSomethingAsync(request);
weblogic.wsee.jaxws.JAXWSProperties
APIで定義されている次のプロパティを使用すると、非同期ハンドラ・インスタンスの状態に依存することなく、ユーザー定義のリクエスト・コンテキスト情報をレスポンス・メッセージに伝播できます。
非同期ハンドラ・インスタンスはいつでも作成される可能性があります(たとえば、クライアントのサーバーがダウンして再起動されるとき)。したがって、非同期ハンドラ・インタフェースにリクエスト・コンテキストを格納しても役に立ちません。
次の表では、JAXWSProperties
のプロパティを定義します。
表4-8 JAXWSProperties APIによってサポートされるプロパティ
プロパティ | 説明 |
---|---|
|
リクエストのメッセージID。クライアントでは、リクエスト・コンテキストにこのプロパティを設定し、リクエストごとのメッセージIDヘッダーの自動生成をオーバーライドできます。 |
|
クライアントまたは通信チャネルで必要なコンテキスト・プロパティ。Webサービス・クライアントでは、コンテキスト・プロパティがシリアライズ可能である場合、リクエスト・メッセージに対してコンテキスト・プロパティを保持できます。これらのプロパティは、非同期ハンドラが呼び出されるときに、 |
|
レスポンスが関連付けられているメッセージID。 |
|
非同期クライアント・トランスポートを使用する同期操作の場合、ブロックしてレスポンスを待機する最大時間。このプロパティのデフォルトは0で、タイムアウトしないことを示します。 |
さらに、Webサービス・クライアントでは、コンテキスト・プロパティがシリアライズ可能である場合、リクエスト・メッセージに対してコンテキスト・プロパティを保持できます。コンテキスト・プロパティは、クライアントまたは通信チャネルで必要な情報を格納できます。メッセージのプロパティは、weblogic.wsee.jaxws.JAXWSProperties.PERSISTENT_CONTEXT
マップ・プロパティの一部として格納し、レスポンス・メッセージが返された後で取得できます。詳細は、「レスポンスへのリクエスト・コンテキストの伝播」を参照してください。
Webサービスの接続作成は、非同期クライアント・トランスポートの代わりとなるクライアント・ポーリング・メカニズムであり、通常はファイアウォールの内側にあるクライアントのサポートを提供します。http://docs.oasis-open.org/ws-rx/wsmc/200702
の接続作成仕様で説明されているように、WebLogic ServerはWS-MakeConnectionバージョン1.1をサポートし、バージョン1.0と下位互換性があります。
接続作成の具体的な機能は次のとおりです。
リクエスト・メッセージの送信に使用された開始トランスポート・リクエストから、レスポンス・メッセージを切り離すことができるようにします(非同期クライアント・トランスポートと似ています)。
アドレス可能ではなく着信接続を受け付けることができないWebサービス・クライアントをサポートします(たとえば、ファイアウォールの内側のクライアント)。
WS-MakeConnectionの仕様で定義されているように、Webサービス・クライアントがMC-Initiatorとして機能し、WebサービスがMC-Receiverとして機能できるようにします。
Webサービスの接続作成の仕様から抜粋した次の図では、標準的な接続作成のメッセージ・フローが示されています。
前の図で示されているように、接続作成のメッセージ・フローは次のようになります。
getQuote()
リクエスト・メッセージが、Webサービス・クライアント(MCイニシエータ)からWebサービス(MCレシーバ)に送信されます。ReplyToヘッダーには、MCイニシエータのUUIDを指定する接続作成の匿名URIが含まれます。
MCレシーバがgetQuote()
メッセージを受信します。ReplyToヘッダーに接続作成匿名URIが含まれる場合はレスポンス・メッセージを接続の戻りチャネルで返送できることを示し、ない場合はクライアントが接続作成ポーリングを使用してレスポンス・メッセージを取得します。
MCレシーバは、空のレスポンス(HTTP 202)をMCイニシエータに返送することで接続を閉じます。
空のレスポンスを受信すると、MCイニシエータはポーリング・メカニズムを初期化して開始し、以降のポーリングをMCレシーバに送信できるようにします。具体的には、MCイニシエータのポーリング・メカニズムは、連続するポーリング間の時間に対して構成されている間隔に有効期限が設定されたタイマーを開始します。
タイマーが切れると、MCイニシエータは、同じ接続作成匿名URI情報を格納した接続作成メッセージをMCレシーバに送信します。
MCレシーバはgetQuote()操作の処理を完了していないので、MCイニシエータに返送できるレスポンスはありません。その結果、MCレシーバは、再び空のレスポンス(HTTP 202)を返送することで現時点では送信できるレスポンスがないことを示し、接続を閉じます。
空のメッセージを受信すると、MCイニシエータは接続作成ポーリング・メカニズムのタイマーを再起動します。
タイマーが切れる前に、getQuote()
操作が完了します。元のリクエストのReplyToヘッダーには接続作成匿名URIが含まれていたので、MCレシーバはレスポンスを格納し、アドレスが一致する次の接続作成メッセージの受信を待ちます。
タイマーが切れると、MCイニシエータは、同じ接続作成匿名URI情報を格納した接続作成メッセージをMCレシーバに送信します。
接続作成メッセージを受信すると、MCレシーバは格納されているレスポンス・メッセージを取得し、受信した接続作成メッセージに対するレスポンスとして送信します。
MCイニシエータはレスポンス・メッセージを受信し、接続作成ポーリング・メカニズムを終了します。
ファイアウォールの内側から非同期呼出しを使用するときは、接続作成トランスポートを使用することをお薦めします。サポートされるプログラミング・モデルの一覧については、表4-2「Webサービスの非同期呼出しのトランスポート・タイプ」を参照してください。
次の項では、Webサービスとクライアントで接続作成を有効にして構成する方法を説明します。
接続作成を有効にするには、接続作成ポリシー・アサーションをWebサービスにアタッチした後、標準のJAX-WSクライアントAPIを使用してクライアントからそのメソッドを呼び出します。ポリシーをWebサービスにアタッチするには、次のいずれかの方法を使用します。
@Policy
アノテーションをJWSファイルに追加します。接続作成ポリシーをアタッチできるのはクラス・レベルだけです。
ポリシーに対する参照をWebサービスのWSDLに追加します。
次の項では、Webサービスで接続作成を有効にするために必要な手順を説明します。
WS-Policyファイルは、WS-Policy仕様に準拠するポリシー・アサーションを含むXMLファイルです。この場合、WS-PolicyファイルにはWebサービスの接続作成のポリシー・アサーションが含まれています。
WebLogic Serverには、標準的な接続作成アサーションを含むWS-Policyファイルがあらかじめパッケージ化されているので、独自のWS-Policyファイルを作成しない場合は、このファイルを使用できます。次の表に、接続作成をサポートするあらかじめパッケージ化されているWS-Policyファイルを示します。場合によっては、ポリシーによって信頼性のあるメッセージングと接続作成の両方が有効化されます。詳細は、付録A「Webサービスの信頼性のあるメッセージングと接続作成のためのあらかじめパッケージ化されたWS-Policyファイル」を参照してください。
注意: 接続作成ポリシーをアタッチできるのはクラス・レベルのみです。メソッド・レベルで接続作成ポリシーをアタッチすることはできません。 |
表4-9 あらかじめパッケージ化されていて接続作成をサポートするWS-Policyファイル
あらかじめパッケージ化されているWS-Policyファイル | 説明 |
---|---|
|
Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。WS-Policy 1.5プロトコルが使用されます。「Mc1.1.xml(WS-Policyファイル)」を参照してください。 |
|
Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。WS-Policy 1.2プロトコルが使用されます。「Mc.xml(WS-Policyファイル)」を参照してください。 |
|
サービス品質に関するポリシー・アサーションを指定します。Webサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。「Reliability1.2_ExactlyOnce_WithMC1.1.xml(WS-Policyファイル)」を参照してください。 |
|
信頼性のあるシーケンスでメッセージを保護するために、 |
Reliability1.0_1.2.xml |
1.2と1.0のWS-Reliableメッセージング・ポリシー・アサーションを結合します。1.2バージョンのポリシー・アサーションはWebサービスでの接続作成のサポートを有効にし、オプションとしてWebサービス・クライアントでの使用方法を指定します。このサンプルは、適切なポリシーの選択に基づいて実行時に適用されるポリシー・アサーションを決定します。「Reliability1.0_1.2.xml(WS-Policyファイル)」を参照してください。 |
WebLogic Serverに含まれる、あらかじめパッケージ化されている接続作成WS-Policyファイルの1つを使用できます。これらのファイルは、ほとんどのユースケースに適合しています。あらかじめパッケージ化されているファイルは変更できません。値がニーズを満たさない場合は、カスタムのWS-Policyファイルを作成する必要があります。たとえば、Webサービスのクライアント側でリクエストされるように接続作成のサポートを構成する場合があります。接続作成ポリシー・アサーションは、WS-PolicyAssertions仕様(https://www.ibm.com/developerworks/library/specification/ws-polas
)に準拠します。
接続作成アサーションを含むカスタムWS-Policyファイルを作成するには、次のガイドラインを使用してください。
WS-Policyファイルのルート要素は常に<wsp:Policy>
です。
Webサービスの接続作成を構成するには、<wsmc:MCSupported>
子要素を追加して、Webサービスの接続作成のサポートを定義します。
<wsmc:MCSupported>
子要素は、1つのポリシー属性Optional
を含み、接続作成をWebサービス・クライアントで構成する必要があるかどうかを指定します。この属性はtrue
またはfalse
に設定でき、デフォルトではtrue
に設定されます。false
に設定した場合は、接続作成の使用は必須であり、ReplyToヘッダーとFaultToヘッダー(指定する場合)の両方に接続作成匿名URIが含まれる必要があります。
次の例では、Webサービスで接続作成を有効にし、Webサービス・クライアントで接続作成を有効にする必要があることを指定しています。この例では、WS-Policy 1.5プロトコルを使用しています。
<?xml version="1.0"?> <wsp15:Policy xmlns:wsp15="http://www.w3.org/ns/ws-policy" xmlns:wsmc="http://docs.oasis-open.org/ws-rx/wsmc/200702"> <wsmc:MCSupported wsp15:Optional="false" /> </wsp15:Policy>
この項では、あらかじめパッケージ化されている接続作成WS-Policyファイルまたはカスタム接続作成WS-Policyファイルを使用して、Webサービスで接続作成を有効にする方法を説明します。カスタム・ポリシー・ファイルの作成の詳細は、「Webサービスの接続作成WS-Policyファイルの作成(オプション)」を参照してください。
接続作成アサーションが含まれるWS-PolicyファイルをWebサービスに追加するよう指定するには、JWSファイルで@Policy
アノテーションを使用します。WebLogic Serverでは、あらかじめパッケージ化されているWS-Policyファイルのセットが提供されます。付録A「Webサービスの信頼性のあるメッセージングと接続作成のためのあらかじめパッケージ化されたWS-Policyファイル」を参照してください。
Webサービスの信頼性のあるメッセージングで@Policy
アノテーションを使用する場合は、次のガイドラインを参照してください。
接続作成ポリシーをアタッチできるのはクラス・レベルのみです。メソッド・レベルで接続作成ポリシーをアタッチすることはできません。
uri
属性を使用して、ポリシー・ファイルのビルド時の場所を以下のように指定します。
独自のWS-Policyファイルを作成した場合は、JWSファイルを基準として相対的に場所を指定します。例:
@Policy(uri="McPolicy.xml", attachToWsdl=true)
この例では、McPolicy.xml
ファイルはJWSファイルと同じディレクトリに置かれています。
あらかじめパッケージ化されているWS-Policyファイルの1つか、共有Java EEライブラリにパッケージ化されているWS-Policyファイルを指定するには、そのポリシー・ファイルの名前とパスとともにpolicy:
接頭辞を使用します。この構文ではビルド時のjwsc
Antタスクに、ファイル・システムの実際のファイルを探させず、Webサービスが、サービスのデプロイ時にWebLogic ServerからWS-Policyファイルを取得することを通知しています。
注意: 共有Java EEライブラリは、様々なエンタープライズ・アプリケーション内にパッケージ化されている複数のWebサービスとWS-Policyファイルを共有する場合に有用です。WS-Policyファイルが共有Java EEライブラリの |
ポリシー・ファイルをWeb上で公開するよう指定するには、次の例に示すとおり、URLと共にhttp:
接頭辞を使用します。
@Policy(uri="http://someSite.com/policies/mypolicy.xml" attachToWsdl=true)
@Policy
アノテーションのattachToWsdl
属性を設定して、ポリシー・ファイルをWebサービスのパブリック規約が記述されたWSDLファイルに付加するかどうかを指定できます。通常は、クライアント・アプリケーションでWebサービスの信頼性のあるメッセージング機能が認識されるよう、パブリックなものとしてポリシーを公開します。そのため、この属性のデフォルト値はtrue
です。
@Policy
アノテーションの詳細は、『Oracle WebLogic Server WebLogic Webサービス・リファレンス』のweblogic.jws.Policyに関する項を参照してください。
次の例では、接続作成を有効にする簡単なJWSファイルを示します。太字で示されたJavaコードに対応するコーディングのガイドラインについては、例の後の説明を参照してください。
package examples.webservices.async import javax.jws.WebMethod; import javax.jws.WebService; import weblogic.jws.Policy; /** * Simple reliable Web Service. */ @WebService(name="HelloWorldPortType", serviceName="HelloWorldService") @Policy(uri="McPolicy.xml", attachToWsdl=true) public class HelloWorldImpl { private static String onewaySavedInput = null; /** * A one-way helloWorld method that saves the given string for later * concatenation to the end of the message passed into helloWorldReturn. */ @WebMethod() public void helloWorld(String input) { System.out.println(" Hello World " + input); onewaySavedInput = input; } /** * This echo method concatenates the saved message from helloWorld * onto the end of the provided message, and returns it. */ @WebMethod() public String echo(String input2) { System.out.println(" Hello World " + input2 + onewaySavedInput); return input + onewaySavedInput; } }
前のサンプルでは、カスタムMcPolicy.xml
ポリシー・ファイルがクラス・レベルでWebサービスにアタッチされています。つまり、ポリシー・ファイルはWebサービスのすべてのパブリック操作に適用されます。接続作成ポリシーをアタッチできるのはクラス・レベルのみです。メソッド・レベルで接続作成ポリシーをアタッチすることはできません。
ポリシー・ファイルはWSDLファイルにアタッチされます。使用可能なあらかじめパッケージ化されているポリシーと、カスタム・ポリシーの作成の詳細は、「Webサービスの接続作成WS-Policyファイルの作成(オプション)」を参照してください。
echo()
メソッドは、@WebMethod
JWSアノテーションでマークされています。これは、このメソッドがecho
というパブリック操作であるということです。@Policy
アノテーションがあるために、この操作では接続作成トランスポート・プロトコルが使用されます。
注意: 接続作成と非同期クライアント・トランスポート機能を一緒に使用することはできません。同じWebサービス・クライアントで両方の機能を有効にしようとすると、エラーが返されます。非同期クライアント・トランスポートの詳細は、「スケーラブルな非同期JAX-WSクライアントの開発(非同期クライアント・トランスポート)」を参照してください。 非同期コールバック・ハンドラ・プログラミング・モデルを使用するときは、非同期ハンドラ機能 |
Webサービス・クライアントで接続作成を有効にするには、Webサービス・プロキシまたはディスパッチを作成するときにパラメータとしてweblogic.wsee.mc.api.McFeature
のインスタンスを渡します。接続作成を有効にする方法の簡単な例を次に示します。
注意: この例では、同期メソッドに同期トランスポートを使用します。同期メソッドのトランスポートとして接続作成を構成する方法は、「同期メソッドのトランスポートとしての接続作成の構成」を参照してください。 |
package examples.webservices.myservice.client; import weblogic.wsee.mc.api.McFeature; ... List<WebServiceFeature> features = new ArrayList<WebServiceFeature>(); ... McFeature mcFeature = new McFeature(); features.add(mcFeature); ... // ... Implement asynchronous handler interface as described in // Developing the Asynchronous Handler Interface. // .... AsyncClientHandlerFeature handlerFeature = new AsyncClientHandlerFeature(handler); features.add(handlerFeature); _features = features.toArray(new WebServiceFeature[features.size()]); BackendService port = _service.getBackendServicePort(_features); ... // Make the invocation. Our asynchronous handler implementation (set // into the AsyncClientHandlerFeature above) receives the response. String request = "Dance and sing"; System.out.println("Invoking DoSomething asynchronously with request: " + request); anotherPort.doSomethingAsync(request); .. } }
次の項では、Webサービス・クライアントで接続作成の特定の機能を構成する方法を説明します。
表4-10では、MCイニシエータがMCレシーバへの接続作成メッセージの送信を停止するまでの最大時間を構成するためのMcFeature
メソッドについて説明します。
表4-11では、空のレスポンス・メッセージを受信した後でMCイニシエータがMCレシーバに接続作成メッセージを送信するまでに経過する必要のある時間を構成するためのMcFeature
メソッドについて説明します。指定されている時間内にMCイニシエータが特定のメッセージに対する空ではないレスポンスを受信しない場合、MCイニシエータは別の接続作成メッセージを送信します。
表4-11 ポーリング間隔を構成するためのメソッド
メソッド | 説明 |
---|---|
|
ポーリング間隔を取得します。 |
|
ポーリング間隔を設定します。 指定する値はXMLスキーマの期間を表す字句形式( |
次の例では、ポーリング間隔を36時間に設定しています。
...
McFeature mcFeature = new McFeature();
mcFeature.setInterval("P0DT36H")
MyService port = service.getMyServicePort(mcFeature);
...
表4-12では、指数関数的バックオフ・フラグを構成するためのMcFeature
メソッドについて説明します。このフラグは、「ポーリング間隔の構成」で説明されているポーリング間隔を、指数関数的バックオフ・アルゴリズムを使用して調整するかどうかを指定します。ポーリング間隔で指定されている時間が経過してもMCイニシエータが空ではないレスポンスを受信しない場合、指数関数的バックオフ・アルゴリズムを使用して、MCイニシエータがレスポンスを受信しないときの連続する再送信のタイミングが設定されます。
指数関数的バックオフ・アルゴリズムは、ポーリングの間隔が、ポーリング間隔を基に指数的に増えるように指定します。たとえば、ポーリング間隔が2秒で、指数関数的バックオフ要素が設定されている場合、レスポンスを受信しない場合の連続ポーリングの間隔は、2、4、8、16、32というように増えていきます。
デフォルト値はfalseであり、連続するポーリングの間隔は指数的に増えず、同じ値が維持されます。
表4-12 指数関数的バックオフを構成するためのメソッド
メソッド | 説明 |
---|---|
|
指数関数的バックオフが有効かどうかを示すブール値を返します。 |
|
指数関数的バックオフ・フラグを設定します。有効な値は |
次の例では、指数関数的バックオフ・フラグを有効にしています。
...
McFeature mcFeature = new McFeature();
mcFeature.setMessageInterval(P0DT36H)
mcFeature.setExponentialBackoff(true);
MyService port = service.getMyServicePort(mcFeature);
...
デフォルトでは、クライアントで接続作成が有効であっても、同期メソッドは同期トランスポートを使用します。同期メソッドのトランスポートとして接続作成を使用するように、クライアントを構成できます。この場合、空ではないレスポンス・メッセージを受信するまで、構成されているポーリング間隔(「ポーリング間隔の構成」を参照)に基づいて、MCイニシエータは接続作成メッセージを送信します。
同期メソッドに使用するトランスポート・プロトコルとして接続作成を構成するには、次のいずれかのメソッドを使用します。
新しいMcFeature()
オブジェクトをインスタンス化するとき、同期メソッドのトランスポート・プロトコルとして接続作成を使用するかどうかを指定するブール値を、パラメータとして渡すことができます。例:
...
McFeature mcFeature = new McFeature(true);
MyService port = service.getMyServicePort(mcFeature);
...
表4-13で示されているMcFeature
メソッドを使用します。例:
...
McFeature mcFeature = new McFeature();
mcFeature.setUseMCWithSyncInvoke(true);
MyService port = service.getMyServicePort(mcFeature);
...
表4-13 同期メソッドのサポートを構成するためのメソッド
メソッド | 説明 |
---|---|
|
同期メソッドのサポートが有効かどうかを示すブール値を返します。 |
|
同期メソッド・サポート・フラグを設定します。有効な値は |
weblogic.wsee.jaxws.JAXWSProperties.REQUEST_TIMEOUT
プロパティを使用すると、同期メソッドがブロックしてレスポンスを待機する最大時間を設定できます。このプロパティのデフォルトは0で、タイムアウトしないことを示します。メッセージ・プロパティの設定の詳細は、「レスポンスへのユーザー定義リクエスト・コンテキストの伝播」を参照してください。
JAX-WS参照実装(RI)は、次のプログラミング・モデルをサポートします。
java.util.concurrent.Future
インタフェースを使用する非同期クライアント・ポーリング。
リクエスト単位の非同期コールバック・ハンドラ。呼出し元のクライアントが、呼出し時にコールバック・ハンドラを指定します。レスポンスが使用できるときは、レスポンスを処理するためにコールバック・ハンドラが呼び出されます。
非同期クライアント・トランスポート機能とは異なり、JAX-WS RIはWS-Addressingに対する非常に制限されたサポートを提供します。次のものが含まれます。
クライアント側アウトバウンドWS-Addressingヘッダーの追加の手動サポート。
レスポンスを受信するためのクライアント側エンドポイントの公開の手動サポート。
正しくないクライアント側プログラミング・モデルの検出はサポートしません(たとえば、同期呼出しはハングします)。
クライアント側またはサービス側の再起動時の情報の保持はサポートしません。
次に示すサンプル・クライアント・ファイル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; // Asynchronous Callback method 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(); // Polling method Response<AddNumbersResponse> addNumbersResp = port.AddNumbersAsync(number1, number2); while (!addNumbersResp.isDone()) { Thread.sleep(100); } AddNumbersResponse reply = addNumbersResp.get(); System.out.println("Server responded through polling with: " + reply.getResponseType()); } }
次の例では、非同期ポーリングと非同期コールバック・ハンドラの両方のプログラミング・モデルを実装する手順を示します。
非同期コールバック・ハンドラを実装するには:
javax.xml.ws.AsyncHandler<T>
インタフェースを実装する非同期ハンドラを作成します。(http://download.oracle.com/javaee/5/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://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.html
を参照)は、非同期計算の結果を表現し、非同期タスクのステータスの確認、結果の取得、タスクの実行の取消を可能にします。
非同期計算の結果を取得します。このサンプルでは、計算の完了を待機するためのタイムアウト値を指定しています。
resp.get(5L, TimeUnit.MINUTES);
コールバック・ハンドラを使用してレスポンス・メッセージにアクセスします。
int result = callbackHandler.getResponse().getReturn();
非同期ポーリング・メカニズムを実装するには:
AddNumbersService
Webサービスをインスタンス化し、非同期バージョンのWebサービス・メソッドaddNumbersAsync
を呼び出します。
Response<AddNumbersResponse> addNumbersResp = port.AddNumbersAsync(number1, number2);
メッセージを受信するまでスリープします。
while (!addNumbersResp.isDone()) { Thread.sleep(100);
レスポンスをポーリングします。
AddNumbersResponse reply = addNumbersResp.get();
WebLogic Serverには、リクエストおよびレスポンス・メッセージの内容に関係なく、ビジネス・コンテキスト(ビジネス・レベルのメッセージIDなど)をリクエスト・メッセージにアタッチして、レスポンスが返されたときにアクセスできるようにする強力な機能があります。たとえば、他の方法ではレスポンス・メッセージで利用できないビジネス・レベルのメッセージIDを使用できます。メッセージにこの情報を伝播することにより、レスポンス・メッセージが返されたときに情報にアクセスできます。
Webサービス・クライアントは、シリアライズ可能でさえあれば任意のリクエスト・メッセージ・コンテキスト・プロパティを格納できます。メッセージ・コンテキスト・プロパティは、weblogic.wsee.jaxws.JAXWSProperties.PERSISTENT_CONTEXT
マップ・プロパティの一部として格納でき、レスポンス・メッセージが返された後で取得できます。
次の例では、PERSISTENT_CONTEXT
マップ・プロパティを使用してメッセージ・コンテキスト・プロパティを定義および設定する方法を示します。
例4-3 メッセージ・コンテキスト・プロパティの設定
import weblogic.wsee.jaxws.JAXWSProperties;
. . .
MyClientPort port = myService.getPort();
Map<String, Serializable> clientPersistProps =
port.getRequestContext().get(JAXWSProperties.PERSISTENT_CONTEXT);
Serializable obj = <my_property>;
clientPersistProps.put("MyProperty", obj);
port.myOperationAsync(<args>, new AsyncHandler<MyOperationResponse>() {
public void handleResponse(Response<MyOperationResponse> res) {
try {
// Get the actual response
MyOperationResponse response = res.get().getReturn();
// Get the property stored when making request. Note, this property did not get
// passed over the wire with the reuqest. The Web services runtime stores it.
Map<String, Serializable> clientPersistProps =
res.getContext().get(JAXWSProperties.PERSISTENT_CONTEXT);
Serializable obj = clientPersistProps.get("MyProperty");
// Do something with MyProperty
} catch (Exception e) {
// Error handling
}
}
});
...
管理コンソールを使用すると、呼出し、エラー、フォルトの数など、Webサービスを非同期に呼び出すクライアントの実行時情報をモニターできます。Webサービス・クライアントをモニターするには、左ペインの「デプロイメント」ノードをクリックし、右ペインに表示される「デプロイメント」表で、Webサービス・クライアントがパッケージ化されているエンタープライズ・アプリケーションを探します。「+」ノードをクリックしてアプリケーションを展開し、Webサービス・クライアントが存在するアプリケーション・モジュールをクリックします。「監視」タブをクリックし、「Webサービス・クライアント」タブをクリックします。
接続作成トランスポート・プロトコルを使用している場合、Webサービスまたはクライアントの接続作成匿名エンドポイントを監視できます。匿名エンドポイントごとに、受信メッセージ数、保留中メッセージ数などの実行時監視情報が表示されます。
「この表のカスタマイズ」をクリックすることで、表に表示される情報をカスタマイズできます。
Webサービスの接続作成匿名エンドポイントを監視するには、左ペインの「デプロイメント」ノードをクリックし、右ペインに表示される「デプロイメント」表でWebサービスがパッケージ化されているエンタープライズ・アプリケーションを探します。「+」ノードをクリックしてアプリケーションを展開すると、「Webサービス」カテゴリにアプリケーション内のWebサービスのリストが表示されます。Webサービス名をクリックし、「監視」→「ポート」→「接続作成」を選択します。
Webサービス・クライアントの接続作成匿名エンドポイントを監視するには、左ペインの「デプロイメント」ノードをクリックし、右ペインに表示される「デプロイメント」表でWebサービス・クライアントがパッケージ化されているエンタープライズ・アプリケーションを探します。「+」ノードをクリックしてアプリケーションを展開し、Webサービス・クライアントが存在するアプリケーション・モジュールをクリックします。「監視」タブをクリックし、「Webサービス・クライアント」タブをクリックします。次に、「監視」→「サーバー」→「接続作成」をクリックします。
Webサービス・クライアントがクラスタで実行するときは、非同期呼出しの非同期レスポンス・エンドポイントにレスポンス・メッセージを正しく配信できるように、特別に考慮する必要があります。「非同期クライアント・トランスポート機能の有効化と構成」で説明したように、非同期レスポンス・エンドポイントはAsyncClientTransportFeatureで定義します。
次の図で示すようなシナリオについて考えます。
前の図で示されているシナリオ:
2つのノードから成るクラスタがクライアント・アプリケーションをホストします。ノード名はServer1とServer2です。クラスタには簡単なロード・バランシング・フロントエンド・プロキシが含まれます。
クライアント・アプリケーションはClientWebAppという名前のWebアプリケーションで、クラスタに同じようにデプロイされています。つまり、Webアプリケーションはクラスタ内の両方のメンバー・サーバーで実行します。
ClientWebAppアプリケーションの外部クライアントが、クラスタのフロントエンド・アドレスを通してリクエストを行います。
次のようなシーケンスについて考えます。
外部クライアントは、クラスタのフロントエンドを介してClientWebAppにページを要求します。
クラスタのフロントエンドはページ・リクエストのロード・バランシングを行い、Server1のClientWebAppにページ・リクエストを送ります。
Server1のClientWebAppはWebサービス・クライアントBackendServiceClientのインスタンスを作成し、バックエンド・サービスBackendServiceと通信します。BackendServiceClientを作成すると、BackendServiceClientを使用して非同期リクエストを行うときに常に非同期レスポンスを受信するための非同期レスポンス・エンドポイントが公開されます。
Server1のClientWebAppはBackendServiceClient.doSomethingAsync()
を呼び出して、バックエンド・サービスで操作を実行します。非同期レスポンス・エンドポイントのアドレスはReplyToアドレスに含まれます。このアドレスはクラスタのフロントエンドのアドレスで開始しており、Server1のアドレスではありません。
クラスタがdoSomething
操作に対するレスポンスを受信します。
クラスタはメッセージをロード・バランシングし、今度はServer2にメッセージを送ります。
Server2にはレスポンスを受信するための非同期レスポンス・エンドポイントがないので、メッセージの配信は失敗します。
この問題を解決するには、次のどちらかを使用できます。
SOAP対応のクラスタ・フロントエンド・プロキシ・プラグイン(WebLogic Server HttpClusterServletなど)を使用します。詳細は、『Oracle WebLogic Serverクラスタの使用』のプロキシ・プラグインの構成に関する項を参照してください。たとえばクラスタのフロントエンド・テクノロジが標準化されているような場合、この解決方法は使用できない場合があります。
クラスタ内のすべてのメンバー・サーバーが非同期レスポンス・エンドポイントを公開して、非同期レスポンス・メッセージを任意のメンバー・サーバーに配信できるようにし、必要に応じてインプレース・クラスタ・ルーティングを介して正しいサーバーにメッセージを転送します。
第2の方法を実装するには、シングルトン・ポート・インスタンスを定義し、その初期化をクライアント・コンテナの初期化時(デプロイメント時)に行うことをお薦めします。クラスタの非同期レスポンス・エンドポイントの初期化のお薦めする方法の例については、例3-2「非同期Webサービス・クライアントのベスト・プラクティスの例」を参照してください。
注意: コンテナの種類によっては、異なる方法でエンドポイントを初期化することもできます。たとえば、クライアントがWebサービスでホストされている場合、Webサービス・コンテナのメソッドに |