Oracle® Fusion Middleware Oracle WebLogic Server JAX-WS Webサービスの開発 12c (12.2.1.3.0) E90362-03 |
|
前へ |
次 |
この章の内容は次のとおりです:
注意:
非同期Webサービス・クライアントを開発するためのロードマップも参照してください。
Webサービスの非同期呼出しをサポートするため、WebLogic Webサービスでは、非同期クライアント・プログラミング・モデルと非同期トランスポートのどちらか一方または両方を使用できます。
表12-1では、非同期クライアント・プログラミング・モデルとトランスポートのタイプの主要な利点、およびWebサービスの非同期呼出しをサポートするために使用できる構成オプションについて説明します。
注意:
2つのportType(非同期操作用に1つとコールバック操作用に1つ)として定義される2つの一方向操作を含む非同期Webサービス用のWSDLを生成する方法は、現在のリリースではサポートされていません。
表12-1 非同期Webサービス呼出しのサポート
タイプ | 説明 | 利点 |
---|---|---|
クライアント・プログラミング・モデル |
Webサービス操作の呼出しに使用される呼出しセマンティクスを記述します(同期または非同期)。 Webサービスを同期的に呼び出す場合、呼出し側のクライアント・アプリケーションは、レスポンスが戻るまで待機してから、処理を続行します。レスポンスが即座に戻る場合であれば、このWebサービス呼出しの方法は適切であると考えられます。しかし、リクエストの処理が遅延する可能性があるため、クライアント・アプリケーションによる処理を続行しレスポンスへの対処は後で行うようにします。 Webサービスを非同期的に呼び出すと、クライアントは処理を中断することなく続行でき、非同期レスポンスが返ると通知を受け取ります。 非同期的呼出しをサポートするには、 |
非同期的に呼び出すことで、Webサービス・クライアントは、Webサービスに対するリクエストを開始し、中断することなく処理を続行し、以降のある時点でレスポンスを受け取ることができます。 |
トランスポート |
トランスポートには、非同期クライアント・トランスポート、接続作成トランスポート、同期トランスポートの3種類があります。トランスポートの各タイプの比較については、表12-2を参照してください。 |
非同期クライアント・トランスポートおよび接続作成トランスポートの主要な利点は次のとおりです。
|
構成 |
Webサービスの非同期呼出しをサポートするようにWebサービスの永続性とバッファリング(オプション)を構成します。 詳細は、「非同期Webサービス呼出しのためのサーバーの構成」を参照してください。 |
Webサービス機能の構成には、次のような利点があります。
|
表12-2では、Webサービス・クライアントからのWebサービスの非同期呼出し(または、構成されている場合は同期呼出し)に対してWebLogic Serverがサポートするトランスポートのタイプを示します。
表12-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
ファイルがあることが前提となっています。詳細は、JAX-WS Webサービスの開発を参照してください。
表12-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サービス・クライアントをコンパイルし、クライアント・アーティファクトのパッケージを作成します。 |
詳細は、「クライアント・アプリケーションのコンパイルと実行」を参照してください |
6 |
Webサービス・クライアントをデプロイします。 |
「WebLogic Webサービスのデプロイとアンデプロイ」を参照してください |
7 |
Webサービス・クライアントをモニターします。 |
WebLogic Server管理コンソールまたはWLSTを使用して、呼出し、エラー、フォルトの数など、Webサービスを非同期に呼び出すクライアントの実行時情報をモニターできます。「非同期Webサービス呼出しのモニタリング」を参照してください。 |
注意:
「JAX-WS参照実装の使用」で説明されているように、標準のJAX-WS RI実装と同期トランスポートを使用してWebサービス・クライアントをプログラミングしている場合は、この手順は必要ありません。
Webサービスの非同期呼出しをサポートするには、Webサービスとクライアントをデプロイするサーバーで、次の表で定義されている機能を構成する必要があります。
表12-4 非同期Webサービス呼出しの構成
機能 | 説明 |
---|---|
永続性 |
Webサービスの永続性は、次の種類の情報を保存するために使用されます。
接続作成トランスポート・プロトコルは、Webサービスの永続性を次のように利用します。
構成ウィザードでWebサービス固有の拡張テンプレートを使用してWebLogic Serverドメインを拡張することにより、Webサービスの永続性を構成できます。あるいは、Oracle WebLogic Server管理コンソールまたはWLSTを使用して、これらの高度な機能に必要なリソースを構成できます。Webサービス永続性の構成の詳細は、「Webサービス・クライアントのためのWebサービス永続性の構成」を参照してください。クライアントとメッセージの情報の保持に使用できるAPIの詳細は、「レスポンスへのリクエスト・コンテキストの伝播」を参照してください。 |
メッセージ・バッファリング |
バッファ付き操作がクライアントによって呼び出されると、リクエストはJMSキューに格納され、WebLogic Serverはリクエストを非同期に処理します。リクエストがまだキューの中にある間にWebLogic Serverがダウンした場合は、WebLogic Serverが再起動してからすぐにリクエストの処理が行われます。メッセージ・バッファリングは、Webサービスをホストしているサーバー上で構成されます。構成情報の詳細は、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>
子要素に渡します。詳細は、「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>
非同期クライアント・トランスポート機能は、スケーラブルな非同期クライアント・プログラミング・モデルを提供します。具体的には、次のような機能があります。
図12-1に示すような、クライアント側の非同期レスポンス・エンドポイントを公開します。
要求された非同期ハンドラの実装を呼び出すサービスの実装を作成して公開します。
すべての非一方向アウトバウンド・メッセージに、WS-Addressingの非匿名ReplyToヘッダーを自動的に追加します。このヘッダーは、公開されたレスポンス・エンドポイントを参照します。
前記の機能を使用して、非同期リクエストとレスポンス・メッセージを関連付けます。
非同期クライアント・トランスポート機能が有効になっているとき、他のすべてのJAX-WSクライアント・プログラミング・モデル(非同期ポーリング、コールバック・ハンドラ、ディスパッチなど)は引き続きサポートされます。非同期クライアント・トランスポート機能が有効になっているとき、この機能を使用するように明示的に構成されていないと、同期Webサービス操作はデフォルトで同期トランスポートを使用します。
次の図では、非同期クライアント・トランスポート機能が使用するメッセージ・フローを示します。
前の図に示すように、次のような処理が行われます。
次の項では、非同期クライアント・トランスポートを使用してスケーラブルな非同期JAX-WSクライアントを開発する方法を説明します。
注意:
接続作成と非同期クライアント・トランスポート機能を一緒に使用することはできません。同じWebサービス・クライアントで両方の機能を有効にしようとすると、エラーが返されます。接続作成の詳細は、「ファイアウォールの内側からの非同期Webサービス・クライアントの使用(接続作成)」を参照してください。
クライアントで非同期クライアント・トランスポート機能を有効にするには、Webサービス・プロキシまたはディスパッチを作成するときにパラメータとしてweblogic.jws.jaxws.client.async.AsyncClientTransportFeature
のインスタンスを渡します。
AsyncClientTransportFeature
によって記述されている非同期レスポンス・エンドポイントは、同じクライアントIDを共有するすべてのクライアント・インスタンスによって使用され、そのクライアントIDを使用する最初のクライアント・インスタンスが公開された時点から有効になります。非同期レスポンス・エンドポイントは、クライアントIDが明示的に破棄されるか、または(たとえば、ホストWebアプリケーションまたはEJBがアンデプロイされて)クライアントのコンテナが非アクティブ化されるまで、発行されたままになります。クライアントIDの管理の詳細は、「クライアントIDの管理」を参照してください
非同期レスポンス・エンドポイント・アドレスは、次の形式を使用して自動的に生成されます。
http://contextAddress:port/context/targetPort-AsyncResponse
各値の説明は次のとおりです。
contextAddress
:
port
: 次のいずれかを指定します。
クラスタ・アプリケーションの場合は、クラスタ・アドレスとポート。
クラスタ・アプリケーションでない場合は、選択されているプロトコルのデフォルトのWebLogic Serverアドレスとポート。
デフォルトのアドレスが定義されていない場合は、指定されているプロトコルの最初のネットワーク・チャネル・アドレス。ネットワーク・チャネルの詳細は、Oracle WebLogic Serverサーバー環境の管理のネットワーク・リソースの構成を参照してください。
context
: 既存のコンテキスト内で実行している場合は、現在のサーブレット・コンテキスト。それ以外の場合は、UUIDによって名前を指定され、スコープがアプリケーションに設定された、新しいコンテキスト。
targetPort
-AsyncResponse
—-AsyncResponse
によって追加されたクライアントによってアクセスされるサービスのポート名。
非同期クライアント・トランスポート機能は、次の項で説明するように構成できます。
AsyncClientTransportFeature()
コンストラクタの形式の詳細は、Oracle WebLogic Server Java APIリファレンスを参照してください。
次に示すように、非同期レスポンス・エンドポイントのアドレスは、AsyncClientTransportFeature
に引数として渡すことで構成できます。
String responseAddress = "http://myserver.com:7001/myReliableService/myClientCallback"; AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(responseAddress); BackendService port = _service.getBackendServicePort(asyncFeature);
指定アドレスは、サーバーまたはクラスタの合法的なアドレスにする必要があります(ネットワーク・チャネルまたはプロキシ・アドレスを含む)。エフェメラル・ポートはサポートされません。指定するコンテキストは、スコープを現在のアプリケーション内に指定されているか、または未使用コンテキストを参照している必要があります。別のデプロイ済アプリケーションにスコープが設定されているコンテキストは参照できません。参照しようとするとエラーがスローされます。
次の表では、非同期レスポンス・エンドポイントのアドレスの構成に使用できるコンストラクタを示します。
表12-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ヘッダーのエンドポイント参照アドレスの構成に使用できるコンストラクタを示します。
表12-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);
指定するコンテキストは、スコープを現在のアプリケーション内に指定されているか、または未使用コンテキストを参照している必要があります。別のデプロイ済みアプリケーションにスコープが設定されているコンテキストは参照できません。
注意:
AsyncClientTransportFeature
に対して空のコンストラクタを使用すると、Webサービスのランタイムは現在の機能がインスタンス化されたコンテナの検出を試み、使用可能なコンテナ・コンテキストを使用してエンドポイントを公開します。
次の表では、非同期レスポンス・エンドポイントのコンテキスト・パスの構成に使用できるコンストラクタを示します。
表12-7 非同期レスポンス・エンドポイントのコンテキスト・パスを構成するためのコンストラクタ
コンストラクタ | 説明 |
---|---|
|
非同期レスポンス・エンドポイントのコンテキスト・パスを構成します。 |
|
次のものを構成します。
|
次のプロパティを構成するときにdoPublish
ブール値をAsycnClientTransportFeature()
に引数として渡すことで、非同期レスポンス・エンドポイントを公開するかどうかを構成できます。
非同期レスポンス・エンドポイントのアドレス。表12-5を参照してください。
ReplyToおよびFaultToヘッダー。表12-6を参照してください。
非同期レスポンス・エンドポイントのコンテキスト・パス。表12-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
ブール・フラグを使用して、同期操作用の非同期クライアント・トランスポートを有効または無効にできます。
非同期レスポンス・エンドポイントのアドレス。表12-5を参照してください。
ReplyToおよびFaultToヘッダー。表12-6を参照してください。
非同期レスポンス・エンドポイントのコンテキスト・パス。表12-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を使用してクライアント・クラスを構築するときは、次に示すように、非同期ハンドラ・インタフェースが生成されます。
例12-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
を初期化し、バックエンド・サービスで呼出しを行うために使用されるポートに非同期ハンドラの実装を接続する方法がわかります。この例は例11-1からの抜粋です。
例12-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
のプロパティを定義します。
表12-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サービスの接続作成の仕様から抜粋した次の図では、標準的な接続作成のメッセージ・フローが示されています。
前の図で示されているように、接続作成のメッセージ・フローは次のようになります。
ファイアウォールの内側から非同期呼出しを使用するときは、接続作成トランスポートを使用することをお薦めします。サポートされているプログラミング・モデルのリストは、表12-2を参照してください。
次の項では、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ファイルを示します。場合によっては、ポリシーによって信頼性のあるメッセージングと接続作成の両方が有効化されます。詳細は、Webサービスの信頼性のあるメッセージングと接続作成のためのあらかじめパッケージ化されたWS-Policyファイルを参照してください。
注意:
接続作成ポリシーをアタッチできるのはクラス・レベルのみです。メソッド・レベルで接続作成ポリシーをアタッチすることはできません。
表12-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に含まれる、あらかじめパッケージ化されているMake Connection WS-Policyファイルの1つを使用できます。これらのファイルは、ほとんどのユースケースに適合しています。あらかじめパッケージ化されているファイルは変更できません。値がニーズを満たさない場合は、カスタムのWS-Policyファイルを作成する必要があります。たとえば、Webサービスのクライアント側で必要に応じてMake Connectionのサポートを構成できます。Make Connectionポリシー・アサーションは、WS-PolicyAssertions仕様に準拠しています。
接続作成アサーションを含むカスタム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ファイルのセットが提供されます。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ライブラリのMETA-INF/policies
またはWEB-INF/policies
ディレクトリに置かれているかぎり、ポリシー・ファイルはWebサービスの同じアーカイブにパッケージ化されている場合と同様に指定できます。ライブラリの作成、およびWebサービスがポリシー・ファイルを見つけることができるようにするための環境設定については、Oracle WebLogic Serverアプリケーションの開発の共有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クライアントの開発(非同期クライアント・トランスポート)」を参照してください。
非同期コールバック・ハンドラ・プログラミング・モデルを使用するときは、非同期ハンドラ機能AsyncClientHandlerFeature
を使用することをお薦めします。詳細は、「非同期ハンドラ・インタフェースの開発」を参照してください。
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サービス・クライアントで接続作成の特定の機能を構成する方法を説明します。
表12-10では、MCイニシエータがMCレシーバへの接続作成メッセージの送信を停止するまでの最大時間を構成するためのMcFeature
メソッドについて説明します。
表12-10 接続作成メッセージ送信の有効時間を構成するためのメソッド
メソッド | 説明 |
---|---|
|
現在構成されている有効期限の値を返します。 |
|
有効期限を設定します。 指定する値はXMLスキーマの期間を表す字句形式( |
表12-11では、空のレスポンス・メッセージを受信した後でMCイニシエータがMCレシーバに接続作成メッセージを送信するまでに経過する必要のある時間を構成するためのMcFeature
メソッドについて説明します。指定されている時間内にMCイニシエータが特定のメッセージに対する空ではないレスポンスを受信しない場合、MCイニシエータは別の接続作成メッセージを送信します。
表12-11 ポーリング間隔を構成するためのメソッド
メソッド | 説明 |
---|---|
|
ポーリング間隔を取得します。 |
|
ポーリング間隔を設定します。 指定する値はXMLスキーマの期間を表す字句形式( |
次の例では、ポーリング間隔を36時間に設定しています。
...
McFeature mcFeature = new McFeature();
mcFeature.setInterval("P0DT36H")
MyService port = service.getMyServicePort(mcFeature);
...
表12-12では、指数関数的バックオフ・フラグを構成するためのMcFeature
メソッドについて説明します。このフラグは、「ポーリング間隔の構成」で説明されているポーリング間隔を、指数関数的バックオフ・アルゴリズムを使用して調整するかどうかを指定します。ポーリング間隔で指定されている時間が経過してもMCイニシエータが空ではないレスポンスを受信しない場合、指数関数的バックオフ・アルゴリズムを使用して、MCイニシエータがレスポンスを受信しないときの連続する再送信のタイミングが設定されます。
指数関数的バックオフ・アルゴリズムは、ポーリングの間隔が、ポーリング間隔を基に指数的に増えるように指定します。たとえば、ポーリング間隔が2秒で、指数関数的バックオフ要素が設定されている場合、レスポンスを受信しない場合の連続ポーリングの間隔は、2、4、8、16、32というように増えていきます。
デフォルト値はfalseであり、連続するポーリングの間隔は指数的に増えず、同じ値が維持されます。
表12-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);
...
表12-13
で示されているMcFeatureメソッドを使用します。例:
...
McFeature mcFeature = new McFeature();
mcFeature.setUseMCWithSyncInvoke(true);
MyService port = service.getMyServicePort(mcFeature);
...
表12-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://docs.oracle.com/javaee/7/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
は、(https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html
を参照)非同期計算の結果を表現し、非同期タスクのステータスの確認、結果の取得、タスクの実行の取消しを可能にします。
非同期計算の結果を取得します。このサンプルでは、計算の完了を待機するためのタイムアウト値を指定しています。
resp.get(5L, TimeUnit.MINUTES);
コールバック・ハンドラを使用してレスポンス・メッセージにアクセスします。
int result = callbackHandler.getResponse().getReturn();
非同期ポーリング・メカニズムを実装するには:
WebLogic Serverには、リクエストおよびレスポンス・メッセージの内容に関係なく、ビジネス・コンテキスト(ビジネス・レベルのメッセージIDなど)をリクエスト・メッセージにアタッチして、レスポンスが返されたときにアクセスできるようにする強力な機能があります。たとえば、他の方法ではレスポンス・メッセージで利用できないビジネス・レベルのメッセージIDを使用できます。メッセージにこの情報を伝播することにより、レスポンス・メッセージが返されたときに情報にアクセスできます。
Webサービス・クライアントは、シリアライズ可能でさえあれば任意のリクエスト・メッセージ・コンテキスト・プロパティを格納できます。メッセージ・コンテキスト・プロパティは、weblogic.wsee.jaxws.JAXWSProperties.PERSISTENT_CONTEXT
マップ・プロパティの一部として格納でき、レスポンス・メッセージが返された後で取得できます。
次の例では、PERSISTENT_CONTEXT
マップ・プロパティを使用してメッセージ・コンテキスト・プロパティを定義および設定する方法を示します。
例12-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
}
}
});
...
WebLogic Server管理コンソールを使用して、呼出し、エラー、フォルトの数など、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の方法を実装するには、シングルトン・ポート・インスタンスを定義し、その初期化をクライアント・コンテナの初期化時(デプロイメント時)に行うことをお薦めします。クラスタの非同期レスポンス・エンドポイントの初期化のお薦めする方法の例については、例11-1を参照してください。
注意:
コンテナの種類によっては、異なる方法でエンドポイントを初期化することもできます。たとえば、クライアントがWebサービスでホストされている場合、Webサービス・コンテナのメソッドに@PostConstruct
アノテーションを付けることができ、そのメソッドでシングルトン・ポートを初期化できます。EJBコンテナでは、シングルトン・ポートを作成するためのトリガー・ポイントとしてejbCreate()
メソッドを使用できます。