Oracle® Fusion Middleware Oracle WebLogic Server JAX-RPC Webサービスの開発 12c (12.1.1) E48037-01 |
|
前 |
次 |
この章では、非同期リクエスト-レスポンスを使用してWebLogic Java API for XML-based RPC (JAX-RPC) Webサービスを呼び出す方法について説明します。
この章では、以下のトピックについて説明します。
Webサービスを同期的に呼び出す場合、呼出し側のクライアント・アプリケーションは、レスポンスが戻るまで待機してから、処理を続行します。レスポンスが即座に戻る場合であれば、このWebサービス呼出しの方法は適切であると考えられます。しかし、リクエストの処理が遅延する可能性があるため、クライアント・アプリケーションによる処理を続行しレスポンスへの対処は後で行うようにする、すなわち、WebLogic Webサービスにおける非同期リクエスト-レスポンス機能を使用すると便利なことがよくあります。
Webサービスの非同期的な呼出しは、WebLogic Webサービスで実行されているクライアントからのみ行います。スタンドアロンのクライアント・アプリケーションから行うことはありません。呼び出されたWebサービスは、まったく変更されません。したがって、Webサービスをホストするアプリケーション・サーバーがhttp://www.w3.org/Submission/2004/SUBM-ws-addressing-20040810/
にあるWS-Addressing仕様をサポートしているかぎり、任意のデプロイ済Webサービス(WebLogicのものも、それ以外のものも)を非同期的に呼び出せます。
クライアントに非同期リクエスト-レスポンスを実装するには、操作を直接呼び出すのではなく、非同期な種類の同じ操作を呼び出します。(この非同期な種類の操作は、jwsc
Antタスクによって自動生成されます。)たとえば、getQuote
という操作を直接呼び出すのではなく、getQuoteAsync
を呼び出します。非同期な種類の操作は、オリジナルの操作が値を戻す場合でも、常にvoid
を戻します。そのため、クライアントには、非同期のレスポンスまたは障害が後で戻されたときにそれを処理するメソッドを組み込みます。これらのメソッド内には、Webサービス操作呼出しに対する戻り値、または潜在的な障害を処理するビジネス・ロジックを置きます。これらのメソッドをJWSコンパイラに対して指定するには、ネーミング・ルールとJWSアノテーションの双方を使用します。たとえば、非同期操作がgetQuoteAsync
である場合、これらのメソッドはonGetQuoteAsyncResponse
およびonGetQuoteAsyncFailure
になります。
注意: Webサービスの信頼性のあるメッセージングやバッファリングなどの他の非同期機能とともに非同期リクエスト-レスポンスを使用する場合については、第11章「非同期機能の併用」を参照してください。本項では、非同期リクエスト-レスポンス機能を単独で使用する方法について説明します。 非同期リクエスト-レスポンス機能は、HTTPでのみ動作します。HTTPSまたはJMSトランスポートでは使用できません。 |
次の手順では、他のWebサービス内に非同期的に操作を呼び出すクライアントWebサービスの作成方法を説明します。この手順では、クライアントWebサービスを実装するJWSファイルをゼロから作成する方法を示しています。既存のJWSファイルを更新する場合は、この手順をガイドとして利用してください。
わかりやすくするために、この手順では以下を想定しています。
クライアントWebサービスの名前はStockQuoteClientService
です。
StockQuoteClientService
サービスは、WSDLが次のURLにある、デプロイ済みのStockQuoteService
サービスのgetQuote(String)
操作を呼び出します。
http://localhost:7001/async/StockQuote?WSDL
さらに、Antベースの開発環境を設定済であり、かつjwsc
Antタスクを実行して生成されたサービスをデプロイするためのターゲットを追加できる、作業用のbuild.xml
ファイルがあることが前提となっています。詳細は、次の項を参照してください。
表7-1 非同期リクエスト-レスポンスを使用する手順
# |
手順 | 説明 |
---|---|---|
1 |
WebLogic Serverインスタンスを構成します。 |
「非同期WebサービスのホストWebLogic Serverインスタンスの構成」の説明に従って、非同期のレスポンス・サービスを構成します。 |
2 |
|
使い慣れたIDEまたはテキスト・エディタを使用します。「非同期のJWSファイルの記述」を参照してください。 |
3 |
|
「非同期リクエスト-レスポンスを使用する場合のbuild.xmlファイルの更新」を参照してください。 |
4 |
Antターゲットを実行して、 |
例: prompt> ant build-clientService |
5 |
|
「WebLogic Webサービスのデプロイとアンデプロイ」を参照してください。 |
StockQuoteClientService
Webサービスを呼び出すと、そのWebサービスがStockQuoteService
Webサービスを呼び出します。この2回目の呼出しは、同期ではなく非同期のものになります。
非同期Webサービスのデプロイ先となるWebLogic Serverインスタンスを構成する際には、Webサービスのランタイムで内部的に使用される、JMSサーバーやモジュールなどのJMSリソースを構成します。
これらのリソースは手作業でも構成できますが、構成ウィザードで、Webサービス固有の拡張テンプレートを使用してWebLogic Serverドメインを拡張することもできます。構成ウィザードを使用すると、必要な構成手順を大幅に簡素化できます。詳細は、「Webサービス機能用のドメイン構成」を参照してください。
注意: または、WLSTを使用してリソースを構成できます。WLSTを使用したドメインの拡張の詳細は、『WebLogic Scripting Toolの理解』の既存ドメインの構成に関する項を参照してください。 Webサービスのリソースを含まないドメインは、Webサービス以外のシナリオおよび非同期のリクエスト/レスポンスが含まれないWebサービス・シナリオにおいて、適切に起動および実行されます。ただし、サーバー・ログに、非同期リソースが構成されていないこと、およびWebサービスの非同期レスポンス・サービスが完全にデプロイされていないことを示すINFOメッセージが表示されます。 |
リソースを手作業で構成する場合、以下の手順を実行します。
表7-2 非同期WebサービスのホストWebLogic Serverインスタンスを手作業で構成する手順
# |
手順 | 説明 |
---|---|---|
1 |
ホストWebLogic Serverインスタンスが格納されたドメインの管理コンソールを起動します。 |
ブラウザで管理コンソールを起動するには、次のURLを入力します。 http://host:port/console 各要素の説明は次のとおりです。
『Oracle WebLogic Server WebLogic Webサービスの理解』の管理コンソールの起動に関する項を参照してください。 |
2 |
JMSサーバーを作成します。 |
JMSサーバーを作成します。JMSサーバーがすでに存在する場合は、新しいJMSサーバーを作成せずにそれを使用できます。 Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJMSサーバーの作成に関する項を参照してください。 |
3 |
JMSモジュールを作成し、キューを定義します。 |
JMSモジュールを作成し、その中にJMSキューを定義します。JMSモジュールがすでに存在する場合は、新しいJMSモジュールを作成せずにそれを使用することもできます。JMSキューを、1つ前の手順で作成したJMSサーバーにターゲット指定します。このJMSキューがローカルであることを必ず指定してください(通常は、ローカルJNDI名の設定により指定できます)。Oracle WebLogic Server管理コンソール・オンライン・ヘルプのJMSシステム・モジュールの作成に関する項とシステム・モジュールのキューの作成に関する項を参照してください。 非同期WebサービスでデフォルトWebサービスのキューを使用する場合は、JMSキューのJNDI名を クラスタ化の考慮事項: クラスタ内でWebサービスの非同期機能を使用する場合は、次の作業を行う必要があります。
|
4 |
ワーク・マネージャを作成します。 |
Oracle WebLogic Server管理コンソール・オンライン・ヘルプのグローバル・ワーク・マネージャの作成に関する項を参照してください。 |
5 |
必要に応じて、現在のドメイン環境をチューニングする(オプション) |
『Oracle WebLogic Serverのパフォーマンスのチューニング』の負荷が高いシステムのチューニングによるWebサービスのパフォーマンス向上に関する項を参照してください。 |
次の例では、StockQuoteClient
というWebサービスを実装する簡単なJWSファイルを示します。このWebサービスには、asyncOperation
という単一のメソッドがあり、これが非同期的に、StockQuote
サービスのgetQuote
メソッドを呼び出します。太字で示されたJavaコードについては、「Webサービスの非同期な呼出しのコーディングに関するガイドライン」で説明します。この非同期呼出しが、同じ操作の同期呼出しとどう違うのかについては、「同期呼出しのサンプル」を参照してください。
package examples.webservices.async_req_res; import weblogic.jws.WLHttpTransport; import weblogic.jws.ServiceClient; import weblogic.jws.AsyncResponse; import weblogic.jws.AsyncFailure; import weblogic.wsee.async.AsyncPreCallContext; import weblogic.wsee.async.AsyncCallContextFactory; import weblogic.wsee.async.AsyncPostCallContext; import javax.jws.WebService; import javax.jws.WebMethod; import examples.webservices.async_req_res.StockQuotePortType; import java.rmi.RemoteException; @WebService(name="StockQuoteClientPortType", serviceName="StockQuoteClientService", targetNamespace="http://examples.org/") @WLHttpTransport(contextPath="asyncClient", serviceUri="StockQuoteClient", portName="StockQuoteClientServicePort") /** * Client Web Service that invokes the StockQuote Service asynchronously. */ public class StockQuoteClientImpl { @ServiceClient(wsdlLocation="http://localhost:7001/async/StockQuote?WSDL", serviceName="StockQuoteService", portName="StockQuote") private StockQuotePortType port; @WebMethod public void asyncOperation (String symbol, String userName) throws RemoteException { AsyncPreCallContext apc = AsyncCallContextFactory.getAsyncPreCallContext(); apc.setProperty("userName", userName); try { port.getQuoteAsync(apc, symbol ); System.out.println("in getQuote method of StockQuoteClient WS"); } catch (RemoteException re) { System.out.println("RemoteException thrown"); throw new RuntimeException(re); } } @AsyncResponse(target="port", operation="getQuote") public void onGetQuoteAsyncResponse(AsyncPostCallContext apc, int quote) { // Get the userName property we set on AsyncPreCallContext String userName = (String)apc.getProperty("userName"); System.out.println("-------------------"); System.out.println(username + " Got quote " + quote ); System.out.println("-------------------"); } @AsyncFailure(target="port", operation="getQuote") public void onGetQuoteAsyncFailure(AsyncPostCallContext apc, Throwable e) { System.out.println("-------------------"); e.printStackTrace(); System.out.println("-------------------"); } }
操作を非同期的に呼び出すための以下のガイドラインは、「非同期のJWSファイルの記述」に記載のサンプルにおいて太字で示したJavaコードに対応しています。これらのガイドラインは、JWSファイル作成のための標準的なガイドラインへの付け加えです。この非同期呼出しが、同じ操作の同期呼出しとどう違うのかについては、「同期呼出しのサンプル」を参照してください。
JWSファイルで操作の非同期呼出しを行う方法は次のとおりです。
非同期リクエスト-レスポンス機能に関連する、次のWebLogic固有のJWSアノテーションをインポートします。
import weblogic.jws.ServiceClient; import weblogic.jws.AsyncResponse; import weblogic.jws.AsyncFailure;
呼び出すWebサービスのポート・タイプのJAX-RPCスタブをインポートします。このスタブは、jwsc
Antタスクによって後から作成されます。スタブ・パッケージは、jwsc
の子要素<clientgen>
のpackageName
属性によって指定され、スタブの名前は呼び出されたWebサービスのWSDLによって決まります。
import examples.webservices.async_req_res.StockQuotePortType;
非同期の呼出し前および呼出し後におけるコンテキストWebLogic APIをインポートします。
import weblogic.wsee.async.AsyncCallContextFactory; import weblogic.wsee.async.AsyncPreCallContext; import weblogic.wsee.async.AsyncPostCallContext;
非同期の呼出し前および呼出し後におけるコンテキストの詳細は、「非同期の呼出し前および呼出し後におけるコンテキストの使用」を参照してください。これらのAPIのさらなるリファレンス情報については、Oracle WebLogic Server Java APIリファレンスのweblogic.wsee.async
に関する項を参照してください。
JWSファイルの本文で、必要な@ServiceClient
JWSアノテーションを使用して、非同期に呼び出すWebサービスのWSDL、名前およびポートを指定します。このアノテーションは、変数のフィールド・レベルで指定します。この変数のデータ型は、呼び出しているWebサービスのJAX-RPCポート・タイプとなります。
@ServiceClient( wsdlLocation="http://localhost:7001/async/StockQuote?WSDL", serviceName="StockQuoteService", portName="StockQuote") private StockQuotePortType port;
@ServiceClient
アノテーションで変数(この場合はport
)をアノテーション付きにする場合、Webサービス・ランタイムはその変数を自動的に初期化およびインスタンス化し、別のWebサービスの非同期呼出しに使用できるようにします。
getQuote
操作を非同期に呼び出すJWSファイルのメソッドで、コンテキスト・ファクトリを使用して、呼出し前の非同期コンテキストを取得します。
AsyncPreCallContext apc = AsyncCallContextFactory.getAsyncPreCallContext();
非同期の呼出し前および呼出し後におけるコンテキストの詳細は、「非同期の呼出し前および呼出し後におけるコンテキストの使用」を参照してください。
呼出し前コンテキストのsetProperty
メソッドを使用して、ユーザー名を格納するプロパティを作成します。
apc.setProperty("userName", userName);
@ServiceClient
アノテーションを付けたスタブを使用して、操作(この場合はgetQuote
)を呼び出します。ただし、直接呼び出すのではなく、その操作の名前の末尾にAsync
が追加された、非同期のものを呼び出します。非同期の種類の操作は、常にvoid
を返します。非同期のコンテキストを最初のパラメータとして渡します。
port.getQuoteAsync(apc, symbol);
非同期に呼び出す各操作について、on
Operationname
AsyncResponse
というメソッドを作成します。Operationname
は操作名で、最初の1文字は常に大文字です。メソッドは、void
を返さなければならず、呼出し後の非同期コンテキストおよび呼び出している操作の戻り値という、2つのパラメータを備えていることが必要です。@AsyncResponse
JWSアノテーションでメソッドをアノテーション付きにします。データ型がJAX-RPCスタブである変数を指定するにはtarget
属性を使用し、非同期に呼び出している操作の名前を指定するにはoperation
属性を使用します。メソッドの本文の中に、操作によって返された値を処理するビジネス・ロジックを入れます。呼出し後コンテキストのgetProperty
メソッドを使用して、非同期メソッドを呼び出す前に呼出し前コンテキストで設定したプロパティを取得します。
@AsyncResponse(target="port", operation="getQuote") public void onGetQuoteAsyncResponse(AsyncPostCallContext apc, int quote) { // Get the userName property we set on AsyncPreCallContext String userName = (String)apc.getProperty("userName"); System.out.println("-------------------"); System.out.println("Got quote " + quote ); System.out.println("-------------------"); }
非同期の呼出し前および呼出し後におけるコンテキストの詳細は、「非同期の呼出し前および呼出し後におけるコンテキストの使用」を参照してください。
非同期に呼び出す各操作について、on
Operationname
AsyncFailure
というメソッドを作成します。Operationname
は操作名で、最初の1文字は大文字です。メソッドはvoid
を返さなければならず、呼出し後の非同期コンテキスト、および呼び出された操作がスローするすべての種類の例外を処理するすべての例外のスーパークラスであるThrowable
オブジェクトという、2つのパラメータを備えていることが必要です。@AsyncFailure
JWSアノテーションでメソッドをアノテーション付きにします。データ型がJAX-RPCスタブである変数を指定するにはtarget
属性を使用し、非同期に呼び出している操作の名前を指定するにはoperation
属性を使用します。メソッド内では、例外の性質を正確に判断し、適切なJavaコードを記述することができます。
@AsyncFailure(target="port", operation="getQuote") public void onGetQuoteAsyncFailure(AsyncPostCallContext apc, Throwable e) { System.out.println("-------------------"); e.printStackTrace(); System.out.println("-------------------"); }
注意:
|
AsyncPreCallContext
およびAsyncPostCallContext
の各APIは、様々な理由によりWebサービスでの使用が可能な非同期のコンテキストを記述します。例:
非同期レスポンスを処理するメソッドがそれぞれの非同期呼出しを見分けられるようコンテキストの前にプロパティを設定する
操作を呼び出しているユーザーの名前、パスワードなどのコンテキスト変数を取得および設定する
メソッドを非同期的に呼び出したJAX-RPCスタブの名前を取得する、およびコンテキストのタイムアウト間隔を設定する
非同期の呼出し前および呼出し後におけるコンテキストを使用するには:
非同期の呼出し前および呼出し後におけるコンテキストWebLogic APIをインポートします。
import weblogic.wsee.async.AsyncCallContextFactory; import weblogic.wsee.async.AsyncPreCallContext; import weblogic.wsee.async.AsyncPostCallContext;
非同期操作を呼び出すJWSファイルのメソッドで、コンテキスト・ファクトリを使用して呼出し前の非同期コンテキストを取得します。例:
AsyncPreCallContext apc = AsyncCallContextFactory.getAsyncPreCallContext();
呼出し前コンテキストのメソッドを使用して、非同期メソッドが呼び出される前に非同期コンテキストに対して処理します。次の例は、呼出し前コンテキストのsetProperty
メソッドを使用して、ユーザー名を格納するプロパティを作成します。
apc.setProperty("userName", userName);
呼出し後コンテキストのメソッドを使用して、非同期メソッドが呼び出された後で非同期コンテキストに対して処理します。次の例は、呼出し後コンテキストのgetProperty
メソッドを使用して、非同期メソッドを呼び出す前に呼出し前コンテキストで設定したプロパティを取得します。
String userName = (String)apc.getProperty("userName");
次のサンプルでは、StockQuote
WebサービスのgetQuote
操作を同期的に呼び出すJWSファイルを示します。このサンプルは、「非同期のJWSファイルの記述」に示した、対応する非同期呼出しとの比較目的でのみ示されています。
package examples.webservices.async_req_res;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.ServiceClient;
import javax.jws.WebService;
import javax.jws.WebMethod;
import java.rmi.RemoteException;
@WebService(name="SyncClientPortType",
serviceName="SyncClientService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="syncClient",
serviceUri="SyncClient",
portName="SyncClientPort")
/**
* Normal service-to-service client that invokes StockQuote service
* synchronously.
*/
public class SyncClientImpl {
@ServiceClient(wsdlLocation="http://localhost:7001/async/StockQuote?WSDL",
serviceName="StockQuoteService", portName="StockQuote")
private StockQuotePortType port;
@WebMethod
public void nonAsyncOperation(String symbol) throws RemoteException {
int quote = port.getQuote(symbol);
System.out.println("-------------------");
System.out.println("Got quote " + quote );
System.out.println("-------------------");
}
}
build.xml
ファイルを更新して、Webサービス操作を非同期的に呼び出すJWSファイルを生成するには、次のようなtaskdefs
およびbuild-clientService
ターゲットを追加します。詳細は、サンプルの後の説明を参照してください。
<taskdef name="jwsc" classname="weblogic.wsee.tools.anttasks.JwscTask" /> <target name="build-clientService"> <jwsc enableAsyncService="true" srcdir="src" destdir="${clientService-ear-dir}" > <jws file="examples/webservices/async_req_res/StockQuoteClientImpl.java" > <clientgen wsdl="http://${wls.hostname}:${wls.port}/async/StockQuote?WSDL" packageName="examples.webservices.async_req_res"/> </jws> </jwsc> </target>
jwsc
Antタスクの完全なクラス名を定義するには、taskdef
Antタスクを使用します。
クライアントWebサービスをコンパイルするjwsc
Antタスクを更新して、<jws>
要素の<clientgen>
子要素を含めます。これにより、デプロイされたStockQuote
WebサービスのJAX-RPCスタブが生成およびコンパイルされるようになります。jwsc
Antタスクでは、これらのスタブが生成されたWARファイルに自動的にパッケージ化されるため、即座にクライアントWebサービスからアクセスできるようになります。この場合のデフォルトでは、jwsc
AntタスクはJAX-RPCスタブ内にWebサービス操作の同期した種類のものと非同期な種類のものを両方とも生成します。このようにするのは、生成されたクラスの1つをStockQuoteClientImpl
JWSファイルでインポートして使用するためです。
デフォルトでは、すべてのWebLogic Serverインスタンスに、非同期リクエスト-レスポンス機能を処理する内部非同期Webサービスがデプロイされます。この内部サービスがデプロイされないようにするには、-Dweblogic.wsee.skip.async.response=true
Javaシステム・プロパティを使用してWebLogic Serverインスタンスを起動します。
非同期サービスを無効にするケースとしては、WebLogic ServerインスタンスをWebLogicクラスタへのWebプロキシとして使用する場合が考えられます。この場合、クラスタ宛に非同期メッセージが送信されても、プロキシ・サーバー上の非同期サービスによって消費されてしまうためクラスタには届きません。このような理由から、プロキシ・サーバー上の非同期サービスは、上記のシステム・プロパティを使用して無効にする必要があります。
Javaシステム・プロパティを指定してWebLogic Serverを構成する方法の詳細は、『Oracle WebLogic Serverサーバーの起動と停止の管理』のWebLogic ServerインスタンスのJavaオプションの指定に関する項を参照してください。
非同期のリクエスト・レスポンス機能を使用するクライアント・アプリケーションでは、操作を直接呼び出さず、プロキシ・サーバーを使用する場合があります。プロキシを使用する理由としては、ファイアウォールの存在や、呼び出されたWebサービスのクラスタへのデプロイメントなどがあります。
この場合、呼び出されたWebサービスをホストするWebLogic Serverインスタンスは、プロキシ・サーバーのアドレスとポートで構成する必要があります。Webサービスがクラスタにデプロイされている場合は、そのクラスタ内のすべてのサーバーを構成することが必要です。
この手順では、ネットワーク接続を管理するための構成可能なWebLogic Serverの主要リソースであるネットワーク・チャネルの作成方法について説明します。ネットワーク・チャネルにより、クラスタのフロントエンド・アドレスにアクセスするための一貫性のある方法を提供できます。ネットワーク・チャネルの詳細は、『Oracle WebLogic Serverサーバー環境の管理』のネットワーク・チャネルの理解に関する項を参照してください。
各サーバー・インスタンスについて、以下の手順を実行します。
Webサービスの呼出しに使用するプロトコル用のネットワーク・チャネルを作成します。ネットワーク・チャネルの名前は、weblogic-wsee-proxy-channel-
XXX
とする必要があります(XXX
はプロトコルを表します)。たとえば、HTTPS用のネットワーク・チャネルを作成する場合、weblogic-wsee-proxy-channel-https
という名前にします。
ネットワーク・チャネルの作成に関する一般情報は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのカスタム・ネットワーク・チャネルの構成に関する項を参照してください。
「外部リスニング・アドレス」および「外部リスニング・ポート」フィールドを、それぞれプロキシ・サーバーのアドレスおよびポートで更新して、ネットワーク・チャネルを構成します。