Oracle® Fusion Middleware Oracle WebLogic Server JAX-RPC を使用した Web サービスの高度な機能のプログラミング 11g リリース 1 (10.3.1) B55544-01 |
|
![]() 戻る |
![]() 次へ |
以下の節では、非同期の要求と応答を使用して 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 サービスの信頼性のあるメッセージングやバッファリングなど、他の非同期機能と共に、非同期の要求と応答を使用する場合については、「非同期機能の併用」を参照してください。この節では、非同期の要求と応答機能を単独で使用する方法を説明しています。非同期の要求と応答機能は、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
ファイルがあることが前提となっています。詳細については、『Oracle Fusion Middleware Oracle WebLogic Server JAX-RPC を使用した Web サービス入門』の以下の節を参照してください。
表 2-1 非同期の要求と応答を使用する手順
# |
手順 | 説明 |
---|---|---|
1 |
WebLogic Server インスタンスをコンフィグレーションする。 |
「非同期 Web サービスのホスト WebLogic Server インスタンスのコンフィグレーション」の説明に従って、非同期の応答サービスをコンフィグレーションする。 |
2 |
|
使い慣れた IDE またはテキスト エディタを使用する。「非同期の JWS ファイルの記述」を参照。 |
3 |
|
|
4 |
Ant ターゲットを実行して、 |
例 : prompt> ant build-clientService |
5 |
通常のように、 |
『Oracle Fusion Middleware Oracle WebLogic Server JAX-RPC を使用した Web サービス入門』の「WebLogic Web サービスのデプロイとアンデプロイ」を参照。 |
StockQuoteClientService
Web サービスを呼び出すと、その Web サービスが StockQuoteService
Web サービスを呼び出します。この 2 回目の呼び出しは、同期ではなく非同期のものになります。
非同期 Web サービスのデプロイ先となる WebLogic Server インスタンスをコンフィグレーションする際には、Web サービスのランタイムで内部的に使用される、JMS サーバやモジュールなどの JMS リソースをコンフィグレーションします。
これらのリソースは手作業でもコンフィグレーションできますが、コンフィグレーション ウィザードで、Web サービス固有の拡張テンプレートを使用して WebLogic Server ドメインを拡張することもできます。コンフィグレーション ウィザードを使用すると、必要なコンフィグレーション手順を大幅に簡略化できます。詳細については、『Oracle Fusion Middleware Oracle WebLogic Server JAX-RPC を使用した Web サービス入門』の「Web サービス機能用のドメイン コンフィグレーション」を参照してください。
注意 : または、WLST を使用してリソースをコンフィグレーションすることもできます。WLST を使用してドメインを拡張する方法の詳細については、『Oracle Fusion Middleware Oracle WebLogic Scripting Tool ガイド』の「既存ドメインのコンフィグレーション」を参照してください。 |
リソースを手作業でコンフィグレーションする場合、以下の手順を実行します。
表 2-2 非同期 Web サービスのホスト WebLogic Server インスタンスを手作業でコンフィグレーションする手順
# |
手順 | 説明 |
---|---|---|
1 |
ホスト WebLogic Server インスタンスが格納されたドメインの Administration Console を起動する。 |
ブラウザで Administration Console を起動するには、次の URL を入力する。 http://host:port/console 各要素の説明は次のとおりである。
『Oracle Fusion Middleware Oracle WebLogic Server JAX-RPC を使用した Web サービス入門』の「Administration Console の起動」を参照。 |
2 |
JMS サーバを作成する。 |
JMS サーバを作成する。JMS サーバがすでに存在する場合は、新しい JMS サーバを作成せずにそれを使用することができる。 『Oracle Fusion Middleware Oracle WebLogic Server Administration Console ヘルプ』の「JMS サーバの作成」を参照。 |
3 |
JMS モジュールを作成し、キューを定義する。 |
JMS モジュールを作成し、その中で JMS キューを定義する。JMS モジュールがすでに存在する場合は、新しい JMS モジュールを作成せずにそれを使用することができる。JMS キューを、1 つ前の手順で作成した JMS サーバに対象指定する。この JMS キューがローカルであることを指定する必要がある (通常は、ローカル JNDI 名の設定により指定できる)。『Oracle Fusion Middleware Oracle WebLogic Server Administration Console ヘルプ』の「JMS システム モジュールの作成」と「システム モジュールのキューの作成」を参照。 非同期 Web サービスでデフォルト Web サービスのキューを使用する場合は、JMS キューの JNDI 名を クラスタ化の考慮事項 : クラスタ内で Web サービスの非同期機能を使用する場合は、以下の作業を行う必要がある。
|
4 |
ワーク マネージャを作成する。 |
『Oracle Fusion Middleware Oracle WebLogic Server Administration Console ヘルプ』の「グローバル ワーク マネージャの作成」を参照。 |
5 |
必要に応じて、現在のドメイン環境をチューニングする (省略可能)。 |
『Oracle Fusion Middleware 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") /** * StockQuote サービスを非同期に呼び出すクライアント Web サービス */ 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) { // AsyncPreCallContext で設定した userName プロパティを取得する 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 Fusion Middleware Oracle WebLogic Server 10.3.1 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) { // AsyncPreCallContext で設定した userName プロパティを取得する 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("-------------------"); }
注意 : @AsyncResponse アノテーションおよび @AsyncFailure アノテーションの使用は、曖昧な点がすべて明瞭化され JWS ファイルが明確かつ理解しやすいものになるためお勧めしますが、必須ではありません。ただし、onXXX メソッドの 1 つで、同じ名前を持つ別々の 2 つの Web サービスからオペレーションを呼び出している 2 つ (またはそれ以上) のスタブからの非同期応答またはエラーを処理する場合は、これらのアノテーションの使用を明示的に避ける必要があります。onXXX メソッドの名前は必ず、上述した正しい命名規約に厳密に準拠するようにしてください。 |
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")
/**
* StockQuote サービスを同期的に呼び出す通常のサービス間
* クライアント
*/
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 Fusion Middleware Oracle WebLogic Server サーバの起動と停止の管理』の「WebLogic Server インスタンスの Java オプションの指定」を参照してください。
非同期の要求応答を使用するクライアント アプリケーションでは、オペレーションを直接呼び出さず、プロキシ サーバを使用する場合があります。プロキシを使用する理由としては、ファイアウォールの存在や、呼び出された Web サービスのクラスタへのデプロイメントなどがあります。
この場合、呼び出された Web サービスをホストする WebLogic Server インスタンスは、プロキシ サーバのアドレスとポートでコンフィグレーションされる必要があります。Web サービスがクラスタにデプロイされている場合は、そのクラスタ内のすべてのサーバをコンフィグレーションすることが必要です。
この手順では、ネットワーク接続を管理するためのコンフィグレーション可能な WebLogic Server の主要リソースであるネットワーク チャネルの作成方法について説明します。ネットワーク チャネルにより、クラスタのフロントエンド アドレスへアクセスするための一貫性のある方法を提供できます。ネットワーク チャネルの詳細については、『Oracle Fusion Middleware Oracle WebLogic Server サーバ環境のコンフィグレーション』の「ネットワーク チャネルについて」を参照してください。
各サーバ インスタンスについて、以下の手順を実行します。
Web サービスの呼び出しに使用するプロトコル用のネットワーク チャネルを作成します。ネットワーク チャネルの名前は、weblogic-wsee-proxy-channel-
XXX
とする必要があります。XXX
は、プロトコルを表します。たとえば、HTTPS 用のネットワーク チャネルを作成する場合、weblogic-wsee-proxy-channel-https
という名前にします。
ネットワーク チャネルの作成に関する全般的な情報については、『Oracle Fusion Middleware Oracle WebLogic Server Administration Console ヘルプ』の「カスタム ネットワーク チャネルのコンフィグレーション」を参照してください。
[外部リスン アドレス] および [外部リスン ポート] フィールドを、それぞれプロキシ サーバのアドレスおよびポートで更新して、ネットワーク チャネルをコンフィグレーションします。