WebLogic Web サービス プログラマーズ ガイド
![]() |
![]() |
![]() |
![]() |
以下の節では、高度な JWS プログラミング トピックに関する情報を提供します。最初の 4 つの節では、さまざまな非同期の機能を個別に実装する方法を説明します。ただし通常、プログラマはこれらの機能を併用します。重要な情報については、「非同期機能の併用」を参照してください。
Web サービスの信頼性のあるメッセージングとは、ある 1 つのアプリケーション サーバで実行中のアプリケーションが、別のアプリケーション サーバで実行中の Web サービスを確実に呼び出せるフレームワークです。ここでは、双方のサーバで WS-ReliableMessaging 仕様が実装されていることが前提となっています。信頼性のある、とは 2 つの Web サービス間でのメッセージの配信を保証できるということです。
注意 : Web サービスの信頼性のあるメッセージングは、WS-ReliableMessaging 仕様が実装された任意の 2 つのアプリケーション サーバ間で機能します。しかしこのマニュアルでは、この 2 つのアプリケーション サーバを、WebLogic Server インスタンスであると想定しています。
WebLogic Web サービス 9.0 は、WS-ReliableMessaging 仕様 (2005 年 2 月) に準拠しています。これは、別々のアプリケーション サーバで実行されている 2 つの Web サービスが、ソフトウェア コンポーネント、システム、またはネットワークに障害が発生していても、確実に通信できる方法について記述したものです。具体的には、この仕様ではソース エンドポイント (つまりクライアント Web サービス) から送り先エンドポイント (つまりオペレーションを確実に呼び出せる Web サービス) へ送信されるメッセージが、1 つまたは複数の配信保証に基づいて確実に配信されるか、そうでなければ必ずエラーが送出される、相互運用性を備えたプロトコルについて説明しています。
信頼性のある WebLogic Web サービスには、以下の配信保証が備わっています。
Web サービスの信頼性のあるメッセージングのアーキテクチャの詳細については、WS-ReliableMessaging 仕様を参照してください。「Web サービスの信頼性のあるメッセージングの使用 : 主な手順」では、信頼性のある Web サービスおよびクライアント Web サービスを作成する方法と、それら Web サービスがデプロイされる 2 つの WebLogic Server インスタンスをコンフィグレーションする方法について説明します。
注意 : Web サービスの信頼性のあるメッセージングは、JMS 転送機能ではサポートされません。
WebLogic Web サービスでは、送り先エンドポイントが Web サービスの信頼性のあるメッセージングの機能と要件を記述および公開できるようにする、WS-Policy ファイルを使用します。WS-Policy 仕様では、Web サービスのポリシーを記述して通信するための、汎用的なモデルと構文が提供されています。
これらの WS-Policy ファイルは、サポートされている WS-ReliableMessaging 仕様のバージョン、ソース エンドポイントの再送信間隔、送り先エンドポイントの確認応答間隔などの特徴が記述された、XML ファイルです。
Web サービスに追加された WS-Policy ファイルの名前は、JWS ファイル内の @Policy
JWS アノテーションを使用して指定します。複数の @Policy
アノテーションをグループ化するには、@Policies
アノテーションを使用します。信頼性のあるメッセージングを行うには、これらのアノテーションを、クラス レベルでのみ使用します。
WebLogic Server では、ユーザ独自の WS-Policy ファイルを作成しない場合に JWS ファイルで指定できる、2 つの単純な WS-Policy ファイルが用意されています。
DefaultReliability.xml
- 信頼性のあるメッセージングのポリシーのアサーションに一般的な値 (非アクティブ タイムアウト 10 分、確認応答の間隔 200 ミリ秒、基本的な再送信間隔 3 秒など) を指定します。実際の WS-Policy ファイルについては、「DefaultReliability.xml WS-Policy ファイル」を参照してください。LongRunningReliability.xml
- 1 つ前に示した、信頼性のあるメッセージングのデフォルト WS-Policy ファイルとほぼ同じですが、アクティビティのタイムアウト間隔に、より大きな値 (24 時間) を指定する点が異なります。実際の WS-Policy ファイルについては、「LongRunningReliability.xml WS-Policy ファイル」を参照してください。あらかじめパッケージ化されているこれらのファイルは、変更することができません。したがって、ファイル内の値がニーズに合わない場合は、独自の WS-Policy ファイルを作成する必要があります。
WebLogic Server 付属のものを使用しない場合の、独自の WS-Policy ファイル作成の詳細については、「Web サービスの信頼性のあるメッセージングの WS-Policy ファイルの作成」を参照してください。信頼性のあるメッセージングのポリシーのアサーションに関するリファレンス情報については、「Web サービスの信頼性のあるメッセージングのポリシー アサーションに関するリファレンス」を参照してください。
<?xml version="1.0"?>
<wsp:Policy
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy"
>
<wsrm:RMAssertion >
<wsrm:InactivityTimeout
Milliseconds="600000" />
<wsrm:AcknowledgementInterval
Milliseconds="200" />
<wsrm:BaseRetransmissionInterval
Milliseconds="3000" />
<wsrm:ExponentialBackoff />
<beapolicy:Expires Expires="P1D"/>
</wsrm:RMAssertion>
</wsp:Policy>
<?xml version="1.0"?>
<wsp:Policy
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy"
>
<wsrm:RMAssertion >
<wsrm:InactivityTimeout
Milliseconds="86400000" />
<wsrm:AcknowledgementInterval
Milliseconds="200" />
<wsrm:BaseRetransmissionInterval
Milliseconds="3000" />
<wsrm:ExponentialBackoff />
<beapolicy:Expires Expires="P1M"/>
</wsrm:RMAssertion>
</wsp:Policy>
WebLogic Web サービスの信頼性のあるメッセージングのコンフィグレーションには、JMS サーバやストア アンド フォワード (SAF) エージェントの作成など標準的な JMS タスクと共に、JWS ファイルへの付加的な JWS アノテーションの追加など Web サービス固有のタスクが必要です。また必要に応じて、あらかじめパッケージ化されているファイルを使用しない場合は、信頼性のある Web サービスの信頼性のあるメッセージング機能を記述した WS-Policy ファイルをユーザ側で作成します。
信頼性のある Web サービスの呼び出しに WebLogic クライアント API を使用している場合、クライアント アプリケーションは WebLogic Server 上で実行される必要があります。したがってコンフィグレーション タスクは、信頼性のある Web サービスを確実に呼び出すクライアント コードを含む Web サービスがデプロイされたソース WebLogic Server インスタンスと、信頼性のある Web サービスそのものがデプロイされた送り先 WebLogic Server インスタンスの、双方の上で実行される必要があります。
以下の手順では、信頼性のある Web サービスと、その信頼性のある Web サービスのオペレーションを確実に呼び出すクライアント Web サービスを作成する方法を説明しています。この手順では、2 つの Web サービスを、何もない状態から実装する JWS ファイルの作成方法を示しています。既存の JWS ファイルを更新する場合は、この手順をガイドとして利用してください。またこの手順では、ソース WebLogic Server インスタンスと送り先 WebLogic Server インスタンスのコンフィグレーション方法も示しています。
WebLogic Server インスタンスが Ant ベースの開発環境を設定して作成されており、かつ jwsc
Ant タスクを実行して、生成された信頼性のある Web サービスをデプロイするためのターゲットを追加できる、作業用の build.xml
ファイルがあることが前提となっています。さらに、Web サービスを確実に呼び出すクライアント Web サービスをホストする、別の WebLogic Server インスタンスを同様に設定してあることも前提となっています。詳細については、以下を参照してください。
これは、信頼性のある Web サービスがデプロイされる WebLogic Server インスタンスです。
「送り先 WebLogic Server インスタンスのコンフィグレーション」を参照してください。
これは、信頼性のある Web サービスを呼び出すクライアント Web サービスがデプロイされる WebLogic Server インスタンスです。
「ソース WebLogic Server インスタンスのコンフィグレーション」を参照してください。
独自の WS-Policy ファイルの作成の詳細については、「Web サービスの信頼性のあるメッセージングの WS-Policy ファイルの作成」を参照してください。
「信頼性のある JWS ファイルに関するプログラミングのガイドライン」を参照してください。
jwsc
タスクの使用に関する全般的な情報については、「jwsc WebLogic Web サービス Ant タスクの実行」を参照してください。
prompt> ant build-mainService deploy-mainService
「信頼性のある Web サービスを呼び出す JWS ファイルに関するプログラミングのガイドライン」を参照してください。
「信頼性のある Web サービスのクライアント用 build.xm ファイルの更新」を参照してください。
prompt> ant build-clientService deploy-clientService
信頼性のある Web サービスがデプロイされる WebLogic Server インスタンスをコンフィグレーションする際には、JMS およびストア アンド フォワード (SAF) リソースがコンフィグレーションされます。以下の高度な手順では、タスクを列挙し、その後それらのタスクを実行するにあたっての詳細が記載された Administration Console オンライン ヘルプを示します。
Administration Console を起動する URL に関する手順については、「Administration Console の起動」を参照してください。
「ファイル ストアの作成」を参照してください。
「JMS サーバの作成」を参照してください。
信頼性のある Web サービスで、デフォルト Web サービスのキューを使用する場合は、JMS キューの JNDI 名を weblogic.wsee.DefaultQueue
に設定します。そうせずに、別の JNDI 名を使用する場合は、必ず「@BufferQueue アノテーションの使用」で説明されている @BufferQueue
アノテーションを使って、この JNDI 名を信頼性のある Web サービスに対して指定します。
Web サービスの信頼性のあるメッセージング機能をクラスタ内で使用している場合は、分散キューではなく、ローカル キューを作成する必要があります。加えて、このキューを明示的にクラスタ内の各サーバに割り当てる必要があります。
「JMS システム モジュールの作成」および「キューの作成」を参照してください。
SAF エージェントを作成する際は、送信エージェントと受信エージェントの両方を有効にするために、必ず [エージェントの種類] フィールドを [両方
] に設定してください。
「ストア アンド フォワード エージェントの作成」を参照してください。
クライアント Web サービスがデプロイされる WebLogic Server インスタンスをコンフィグレーションする際には、JMS およびストア アンド フォワード (SAF) リソースがコンフィグレーションされます。以下の高度な手順では、タスクを列挙し、その後それらのタスクを実行するにあたっての詳細が記載された Administration Console オンライン ヘルプを示します。
Administration Console を起動する URL に関する手順については、「Administration Console の起動」を参照してください。
「ファイル ストアの作成」を参照してください。
「JMS サーバの作成」を参照してください。
SAF エージェントを作成する際は、送信エージェントと受信エージェントの両方を有効にするために、必ず [エージェントの種類] フィールドを [両方
] に設定してください。
「ストア アンド フォワード エージェントの作成」を参照してください。
WS-Policy ファイルは、WS-Policy 仕様に準拠するポリシー アサーションを含む XML ファイルです。この場合には、WS-Policy ファイルに Web サービスの信頼性のあるメッセージング ポリシーのアサーションが含まれています。
WebLogici Server に含まれる 2 つのデフォルトの信頼性のあるメッセージング WS-Policy ファイルのうち一方を使用できます。これらのファイルは、ほとんどの場合に適合しています。しかし、これらのファイルは変更ができないので、ニーズに合わない場合は独自のファイルを作成することが必要です。付属の WS-Policy ファイルについては、「Web サービスの信頼性のあるメッセージングをコンフィグレーションするための WS-Policy ファイルの使用」を参照してください。この節のこれ以降では、ユーザ独自の WS-Policy ファイルの作成方法について説明します。
WS-Policy ファイルのルート要素は <Policy>
です。Web サービスの信頼性のあるメッセージング ポリシーのアサーションを使用するには、これに以下のネームスペース宣言が含まれていることが必要です。
<wsp:Policy
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy">
Web サービスの信頼性のあるメッセージング ポリシーのアサーションはすべて、<wsrm:RMAssertion>
要素の内部でラップします。wsrm:
ネームスペースを使用するアサーションは、WS-ReliableMessaging 仕様で定義される標準的なアサーションです。beapolicy:
ネームスペースを使用するアサーションは、WebLogic 固有のものです。「Web サービスの信頼性のあるメッセージングのポリシー アサーションに関するリファレンス」を参照してください。
Web サービスの信頼性のあるメッセージングのアサーションは、すべて任意指定なので、デフォルト値が不適切なものだけを設定します。次のアサーションを指定できます。
<wsrm:InactivityTimeout>
- 非アクティブ間隔を定義する、Milliseconds
属性で指定されるミリ秒数。この時間が経過した時点で、送り先エンドポイントがソース エンドポイントからのメッセージを受け取っていなければ、送り先エンドポイントは、処理が行われずシーケンスは終了したものと見なします。これは、ソース エンドポイントについても同様です。デフォルトでは、シーケンスがタイムアウトすることはありません。 <wsrm:AcknowledgmentInterval>
- 送り先エンドポイントがスタンドアロンの確認応答を送信しなければならない最大間隔 (ミリ秒単位)。デフォルト値は、送り先エンドポイントの WebLogic Server インスタンス上の SAF エージェントによって設定されます。<wsrm:BaseRetransmissionInterval>
- ソース エンドポイントがメッセージを送信してから、そのメッセージの確認応答を受け取っていない場合に再送信を行うまでの間隔 (ミリ秒単位)。デフォルト値は、ソース エンドポイントの WebLogic Server インスタンス上の SAF エージェントによって設定されます。<wsrm:ExponentialBackoff>
- 再送信の間隔が、指数関数的なバックオフ アルゴリズムを使用して調整されることを指定。この要素には属性はありません。 <beapolicy:Expires>
- 信頼性のある Web サービスの有効期限が切れ、これ以上のシーケンス メッセージを受け付けなくなるまでの時間の長さ。デフォルト値では、有効期限が切れることはありません。この要素には、Expires
という 1 つの属性があります。この属性のデータ型は XML スキーマ期間型です。たとえば、有効期限までを 1 日と設定する場合は、<beapolicy:Expires Expires="P1D" />
とします。<beapolicy:QOS>
- 「Web サービスの信頼性のあるメッセージングの使用」で説明されている、配信保証レベル。この要素には、QOS
という 1 つの属性があります。これは、AtMostOnce
、AtLeastOnce
、ExactlyOnce
の各値のうちの 1 つに設定します。また、メッセージを順序通りにすることを指定するために InOrder
文字列を含めることもできます。デフォルト値は、ExactlyOnce InOrder
です。この要素は通常、設定されません。 次の例では、簡単な Web サービスの信頼性のあるメッセージングの WS-Policy ファイルを示します。
<?xml version="1.0"?>
<wsp:Policy wsp:Name="ReliableHelloWorldPolicy"
xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:beapolicy="http://www.bea.com/wsrm/policy">
<wsrm:RMAssertion>
<wsrm:InactivityTimeout
Milliseconds="600000" />
<wsrm:AcknowledgementInterval
Milliseconds="2000" />
<wsrm:BaseRetransmissionInterval
Milliseconds="500" />
<wsrm:ExponentialBackoff />
</wsrm:RMAssertion>
</wsp:Policy>
この節では、信頼性のある Web サービスを実装する JWS ファイルの作成方法を説明します。
信頼性のある Web サービスを実装する JWS ファイルでは、次の JWS アノテーションが使用されます。
@weblogic.jws.Policy
- 必須。「@Policy Annotation の使用」を参照してください。@javax.jws.OneWay
- 一緒に非同期の要求と応答機能を使用することなく、単独で Web サービスの信頼性のあるメッセージングを使用している場合のみ、必須。「@OneWay アノテーションの使用」および「非同期機能の併用」を参照してください。@weblogic.jws.BufferQueue
- 任意。「@BufferQueue アノテーションの使用」を参照してください。@weblogic.jws.ReliabilityBuffer
- 任意。「@ReliabilityBuffer アノテーションの使用」を参照してください。次のサンプルでは、信頼性のある Web サービスを実装する簡単な JWS ファイルを示します。太字で示された Java コードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。
package examples.webservices.reliable;
import javax.jws.WebMethod;
import javax.jws.WebService;import javax.jws.Oneway;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.ReliabilityBuffer;
import weblogic.jws.BufferQueue;
import weblogic.jws.Policy;
/**
* 簡単な信頼性のある Web サービス
*/
@WebService(name="ReliableHelloWorldPortType",
serviceName="ReliableHelloWorldService")
@WLHttpTransport(contextPath="ReliableHelloWorld",
serviceUri="ReliableHelloWorld",
portName="ReliableHelloWorldServicePort")
@Policy(uri="ReliableHelloWorldPolicy.xml",
direction=Policy.Direction.both,
attachToWsdl=true)
@BufferQueue(name="webservices.reliable.queue")
public class ReliableHelloWorldImpl {
@WebMethod()@Oneway()
@ReliabilityBuffer(retryCount=10, retryDelay="10 seconds")
public void helloWorld(String input) {
System.out.println(" Hello World " + input);
}
}
このサンプルでは、ReliableHelloWorldPolicy.xml
ファイルがクラス レベルで Web サービスに追加されています。つまり、ポリシー ファイルは Web サービスのすべてのパブリック オペレーションに適用されます。ポリシー ファイルは、リクエスト Web サービス メッセージ (信頼性のあるメッセージング機能によって要求される) のみに適用され、WSDL ファイルに追加されます。
WebLogic Server が、Web サービスの信頼性のあるメッセージングを有効化するために内部で使用する JMS キューの JNDI 名は、@BufferQueue
アノテーションで指定されているように、webservices.reliable.queue
です。
helloWorld()
メソッドは、@WebMethod
と @OneWay
、どちらの JWS アノテーションでもマークされています。これは、このメソッドが helloWorld
というパブリック オペレーションであるということです。@Policy
アノテーションがあるために、オペレーションを確実に呼び出すことができます。@ReliabilityBuffer
アノテーションに記述されているとおり、Web サービスのランタイムでは、最大で 10 回、10 秒間隔で、信頼性のあるメッセージをサービスに配信しようとします。たとえば、トランザクションがロールバックされる場合や、コミットしない場合などには、メッセージの再配信が必要となることがあります。
注意 : Web サービスの信頼性のあるメッセージングを単独で (その他の非同期機能を伴わずに) コンフィグレーションしている場合、確実に呼び出せるのは、一方向のオペレーションのみです。つまり、実装メソッドは値を返すことができず、明示的に void
を返すことになります。信頼性のあるオペレーションからの戻り値が必要な場合は、非同期の要求と応答機能も使用する必要があります。「非同期の要求と応答を使用した Web サービスの呼び出し」および「非同期機能の併用」を参照してください。
信頼性のあるメッセージングのアサーションが含まれる WS-Policy ファイルを Web サービスに追加するよう指定するには、JWS ファイルで @Policy
アノテーションを使用します。
独自に記述する代わりに使用できる、WebLogic Server で用意されている 2 つの WS-Policy ファイル (DefaultReliability.xml
および LongRunningReliability.xml
) については、「Web サービスの信頼性のあるメッセージングをコンフィグレーションするための WS-Policy ファイルの使用」を参照してください。
@Policy
アノテーションを Web サービスの信頼性のあるメッセージングに使用する場合、以下の要件を満たしている必要があります。
@Policy
アノテーションをクラス レベルでのみ指定する。 @Policy
アノテーションの direction
属性はデフォルト値 Policy.Direction.both
にのみ設定する。 uri
属性を使用して、ポリシー ファイルのビルド時の場所を以下のように指定します。
@Policy(uri="ReliableHelloWorldPolicy.xml",
direction=Policy.Direction.both,
attachToWsdl=true)
policy:
プレフィックスを使用する。この構文ではビルド時の jwsc
Ant タスクに、ファイル システムの実際のファイルを探させず、Web サービスが、サービスのデプロイ時に WebLogic Server から WS-Policy ファイルを取得することを通知しています。この構文は、あらかじめパッケージ化されている WS-Policy ファイルの一方を指定する際、または共有の J2EE ライブラリ内にパッケージ化されている WS-Policy ファイルを指定する際に使用します。 注意 : 共有 J2EE ライブラリは、さまざまなエンタープライズ アプリケーション内にパッケージ化されている複数の Web サービスと、WS-Policy ファイルを共有する場合に有用です。WS-Policy ファイルが共有 J2EE ライブラリの META-INF/policies
または WEB-INF/policies
ディレクトリに置かれている限り、ポリシー ファイルは Web サービスの同じアーカイブにパッケージ化されている場合と同様に指定できます。ライブラリの作成、および Web サービスがポリシー ファイルを見つけることができるようにするための環境設定については、「Creating Shared J2EE Libraries and Optional Packages」を参照してください。
http:
プレフィックスを使用する。
@Policy(uri="http://someSite.com/policies/mypolicy.xml"
direction=Policy.Direction.both,
attachToWsdl=true)
また、@Policy
アノテーションの attachToWsd
属性を設定して、ポリシー ファイルを Web サービスのパブリック規約が記述された WSDL ファイルに付加するかどうかを指定することもできます。通常は、クライアント アプリケーションで Web サービスの信頼性のあるメッセージング機能が認識されるよう、パブリックなものとしてポリシーを公開します。そのため、この属性のデフォルト値は true
です。
Web サービスの信頼性のあるメッセージングにおいて非同期の要求と応答機能を使用していない場合、@OneWay
JWS アノテーションを使用して、信頼性のあるオペレーションは一方向にしか呼び出せないことを明示的に指定する必要があります。このアノテーションには属性はありません。
定義では、一方向のオペレーションを実装するメソッドは値を返すことができない、すなわち void
を返すことになります。
他の非同期機能 (特に非同期の要求と応答) を使用する、信頼性のあるメッセージングについては、「非同期機能の併用」を参照してください。
他に指定がない限り、WebLogic Server では信頼性のあるメッセージの内部格納に、デフォルトの Web サービス JMS キュー (weblogic.wsee.DefaultQueue
) を使用します。別のキューを使用する場合は、この JWS アノテーションで JNDI 名を指定します。
デフォルトの JMS キューと、このアノテーションで指定されたキューの双方を作成してからでなければ、信頼性のあるオペレーションを正常に呼び出すことはできません。詳細については、「送り先 WebLogic Server インスタンスのコンフィグレーション」を参照してください。
このアノテーションは、WebLogic Server による JMS キューから Web サービス実装へのメッセージ配信試行回数 (デフォルトでは 3 回)、およびサーバが待機すべき再試行間隔 (デフォルトでは 5 秒) の指定に使用します。
再試行回数の指定には retryCount
属性を、待機時間の指定には retryDelay
属性を使用します。retryDelay
属性の形式としては、数字の後に以下の文字列のうち 1 つを続けます。
たとえば、再試行回数を 20、再試行の遅延を 2 日と指定するには、次の構文を使用します。
@ReliabilityBuffer(retryCount=20, retryDelay="2 days")
WebLogic クライアント API を使用している場合は、信頼性のある Web サービスを Web サービス内から呼び出す必要があります。スタンドアロンのクライアント アプリケーションからは呼び出せません。
次の例では、「信頼性のある JWS ファイルに関するプログラミングのガイドライン」で説明した、サービスから信頼性のあるオペレーションを呼び出す Web サービス用の簡単な JWS ファイルを示します。太字で示された Java コードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。
package examples.webservices.reliable;
import java.rmi.RemoteException;
import javax.jws.WebMethod;
import javax.jws.WebService;
import weblogic.jws.WLHttpTransport;import weblogic.jws.ServiceClient;
import examples.webservices.reliable.ReliableHelloWorldPortType;
@WebService(name="ReliableClientPortType",
serviceName="ReliableClientService")
@WLHttpTransport(contextPath="ReliableClient",
serviceUri="ReliableClient",
portName="ReliableClientServicePort")
public class ReliableClientImpl
{@ServiceClient(
wsdlLocation="http://localhost:7001/ReliableHelloWorld/ReliableHelloWorld?WSDL",
serviceName="ReliableHelloWorldService",
portName="ReliableHelloWorldServicePort")
private ReliableHelloWorldPortType port;
@WebMethod
public void callHelloWorld(String input, String serviceUrl)
throws RemoteException {
port.helloWorld(input);
System.out.println(" Invoked the ReliableHelloWorld.helloWorld operation reliably." );
}
}
信頼性のある Web サービスを呼び出す JWS ファイルをプログラミングする際には、以下のガイドラインに従います。ガイドラインのコード例は、上述のサンプル内では太字で示されています。
@ServiceClient
JWS アノテーションをインポートする。
import weblogic.jws.ServiceClient;
clientgen
Ant タスクによって、後から作成されます。スタブ パッケージは、clientgen
の packageName
属性によって指定され、スタブの名前は呼び出された Web サービスの WSDL によって決まります。
import examples.webservices.reliable.ReliableHelloWorldPortType;
@ServiceClient
JWS アノテーションを使用して、呼び出し対象の信頼性のある Web サービスの WSDL、名前、およびポートを指定する。このアノテーションは、プライベート変数のフィールド レベルで指定します。この変数のデータ型は、呼び出している Web サービスの JAX-RPC ポートの種類となります。
@ServiceClient(
wsdlLocation="http://localhost:7001/ReliableHelloWorld/ReliableHelloWorld?WSDL",
serviceName="ReliableHelloWorldService",
portName="ReliableHelloWorldServicePort")
private ReliableHelloWorldPortType port;
@ServiceClient
アノテーションを付けたスタブを使用して、信頼性のあるオペレーションを呼び出す。
port.helloWorld(input);
build.xml
を更新して、信頼性のある Web サービスのオペレーションを呼び出す JWS ファイルを生成するには、次のような taskdefs
および build-reliable-client
ターゲットを追加します。詳細については、サンプルの後の説明を参照してください。
<path id="ws.client.class.path">
<pathelement path="${tempjar-dir}"/>
<pathelement path="${java.class.path}"/>
</path>
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<taskdef name="clientgen"
classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
<target name="build-reliable-client">
<clientgen
wsdl="http://${wls.destination.host}:${wls.destination.port}/ReliableHelloWorld/ReliableHelloWorld?WSDL"
destDir="${tempjar-dir}"
packageName="examples.webservices.reliable"/>
<javac
source="1.5"
srcdir="${tempjar-dir}"
destdir="${tempjar-dir}"
includes="**/*.java"/>
<jwsc
srcdir="src"
destdir="${client-ear-dir}"
classpathref="ws.client.class.path">
<jws
file="examples/webservices/reliable/ReliableClientImpl.java"/>
</jwsc>
<copy todir="${client-ear-dir}/app-inf/classes">
<fileset dir="${tempjar-dir}" />
</copy>
</target>
jwsc
および clientgen
Ant タスクの完全なクラス名を定義するには、taskdef
Ant タスクを使用します。
jwsc
Ant タスクを実行する前に、まず clientgen
を使用して、デプロイされる ReliableHelloWorld
Web サービスの JAX-RPC スタブを生成およびコンパイルする必要があります。これを行うのは、ReliableClientImpl
JWS ファイルで、生成されたクラスのうち 1 つがインポートされて使用されるためです。これらのクラスが既に存在していなければ、jwsc
タスクは失敗します。jwsc
Ant タスクを実行する場合、classpathref
属性を使用して、clientgen
がアーティファクトを生成する一時ディレクトリを CLASSPATH に追加します。
jwsc
がすべてのアーティファクトを EAR ディレクトリの中に生成したら、copy
Ant タスクを使用して、clientgen
により生成されたアーティファクトを、EAR の APP-INF/classes
ディレクトリへコピーし、ReliableClientService
Web サービスがこれらを見つけられるようにします。
注意 : APP-INF/classes
ディレクトリは、エンタープライズ アプリケーション内のクラスを共有するための WebLogic 固有の機能です。
Web サービスを同期的に呼び出す場合、呼び出し側のクライアント アプリケーションは、応答が返るまで待機してから、処理を続行します。応答が即座に返る場合であれば、この Web サービス呼び出しの方法は、適切であると考えられます。しかし、要求の処理が遅延される可能性があるため、クライアント アプリケーションによる処理を続行し、応答への対処は後で行うようにする、すなわち、WebLogic Web サービスにおける非同期の要求と応答機能を使用すると便利なことがよくあります。
Web サービスの非同期的な呼び出しは、WebLogic Web サービスで実行されているクライアントからのみ行います。スタンドアロンのクライアント アプリケーションからは決して行いません。呼び出された Web サービスは、まったく変更されません。したがって、Web サービスをホストするアプリケーション サーバが WS-Addressing 仕様をサポートしている限り、任意のデプロイ済み Web サービス (WebLogic のものも、それ以外のものも) を非同期的に呼び出せます。
クライアントで非同期の要求と応答を実装するには、オペレーションを直接呼びだすよりも、非同期な種類の同じオペレーションを呼び出します (この非同期な種類のオペレーションは、clientgen
Ant タスクによって自動生成されます)。たとえば、getQuote
というオペレーションを直接呼び出すのではなく、getQuoteAsync
を呼び出します。非同期な種類のオペレーションは、オリジナルのオペレーションが値を返す場合でも、常に void
を返します。その後クライアントに、非同期の応答を処理するメソッド、または後で応答が返る場合はエラーを格納します。これらのメソッド内には、Web サービスのオペレーション呼び出しに対する戻り値、または潜在的なエラーを処理する、すべてのビジネス ロジックを置きます。これらのメソッドを JWS コンパイラに対して指定するには、命名規約と JWS アノテーションの双方を使用します。たとえば、非同期のオペレーションが getQuoteAsync
というものである場合、これらのメソッドは onGetQuoteAsyncResponse
および onGetQuoteAsyncFailure
になり得ます。
注意 : Web サービスの信頼性のあるメッセージングやバッファリングなど、他の非同期機能と共に、非同期の要求と応答を使用する場合については、「非同期機能の併用」を参照してください。この節では、非同期の要求と応答機能を単独で使用する方法を説明しています。
注意 : 非同期の要求と応答機能は、HTTP でのみ動作します。HTTPS または JMS 転送では使用できません。
次の手順では、他の Web サービス内に非同期的にオペレーションを呼び出すクライアント Web サービスの作成方法を説明します。この手順では、クライアント Web サービスを、何もない状態から実装する JWS ファイルの作成方法を示しています。既存の JWS ファイルを更新する場合は、この手順をガイドとして利用してください。
分かりやすくするために、この手順では以下の想定を行っています。
StockQuoteClientService
と呼ばれている。StockQuoteClientService
サービスは、WSDL が次の URL にある、デプロイ済みの StockQuoteService
サービスの getQuote(String)
オペレーションを呼び出す。
http://localhost:7001/async/StockQuote?WSDL
さらには、Ant ベースの開発環境を設定済みであり、かつ jwsc
Ant タスクを実行して、生成されたサービスをデプロイするためのターゲットを追加できる、作業用の build.xml
ファイルがあることが前提となっています。「一般的な Web サービスの使用例とサンプル」、「WebLogic Web サービスの反復的な開発」、および「JWS ファイルのプログラミング」を参照してください。
StockQuoteClientService
Web サービスを実装する新しい JWS ファイルを作成するか、既存の JWS ファイルを更新します。「非同期の JWS ファイルの記述」を参照してください。
build.xml
ファイルを更新して、StockQuoteService
Web サービスに対して clientgen
Ant タスクを実行し、StockQuoteClientService
を実装する JWS ファイルをコンパイルします。clientgen
Ant タスクは、呼び出している Web サービスの非同期な種類のものを自動的に生成します。「非同期の要求と応答を使用する場合の build.xml ファイルの更新」を参照してください。
prompt> ant build-clientService
「WebLogic Web サービスのデプロイとアンデプロイ」を参照してください。
StockQuoteClientService
Web サービスを呼び出すと、その Web サービスが StockQuoteService
Web サービスを呼び出します。この 2 回目の呼び出しは、同期ではなく非同期のものになります。
次のサンプルでは、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) throws RemoteException {
AsyncPreCallContext apc = AsyncCallContextFactory.getAsyncPreCallContext();
apc.setProperty("symbol", symbol);
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) {
System.out.println("-------------------");
System.out.println("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 ファイルにオペレーションの非同期呼び出しを行う方法は次のとおりです。
import weblogic.jws.ServiceClient;
import weblogic.jws.AsyncResponse;
import weblogic.jws.AsyncFailure;
clientgen
Ant タスクによって、後から作成されます。スタブ パッケージは、clientgen
の packageName
属性によって指定され、スタブの名前は呼び出された Web サービスの WSDL によって決まります。
import examples.webservices.async_req_res.StockQuotePortType;
import weblogic.wsee.async.AsyncCallContextFactory;
import weblogic.wsee.async.AsyncPreCallContext;
import weblogic.wsee.async.AsyncPostCallContext;
AsyncPreCallContext
および AsyncPostCallContext
API には、さまざまな理由により使用が可能な非同期のコンテキストが記述されています。非同期応答を処理するメソッドがそれぞれの非同期呼び出しを見分けられるようコンテキストの前にプロパティを設定するため、オペレーションを呼び出しているユーザの名前、パスワード等のコンテキスト変数を設定および取得するため、メソッドを非同期的に呼び出した JAX-RPC スタブの名前を取得するため、そしてコンテキストのタイムアウト間隔を設定するためというのがその理由です。
これらの API のさらなるリファレンス情報については、Javadocs を参照してください。
@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
メソッドを使用して、名前と値が getQuote
メソッドに対するパラメータと同じであるプロパティを作成する。
apc.setProperty("symbol", symbol);
@ServiceClient
アノテーションを付けたスタブを使用して、オペレーション (この場合は getQuote
) を呼び出す。ただし、直接呼び出すのではなく、そのオペレーションの名前の末尾に Async
が追加された、非同期のものを呼び出します。非同期の種類のオペレーションは、常に void
を返します。非同期のコンテキストを最初のパラメータとして渡します。
port.getQuoteAsync(apc, symbol);
on
Operationname
AsyncResponse
というメソッドを作成する。Operationname
はオペレーション名で、最初の 1 文字は常に大文字です。メソッドは、void
を返さなければならず、呼び出し後の非同期コンテキストおよび呼び出しているオペレーションの戻り値という、 2 つのパラメータを備えていることが必要です。@AsyncResponse
JWS アノテーションでメソッドをアノテーション付きにします。データ型が JAX-RPC スタブである変数を指定するには target
属性を使用し、非同期に呼び出しているオペレーションの名前を指定するには operation
属性を使用します。メソッドの本文の中に、オペレーションによって返された値を処理するビジネス ロジックを入れます。
@AsyncResponse(target="port", operation="getQuote")
public void onGetQuoteAsyncResponse(AsyncPostCallContext apc,
int quote) {
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
メソッドの名前は必ず、上述した正しい命名規約に厳密に準拠するようにしてください。
以下のサンプルでは、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 サービスを同期的に呼び出す通常の ole サービス間
* クライアント
*/
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
ターゲットを追加します。詳細については、サンプルの後の説明を参照してください。
<path id="ws.clientService.class.path">
<pathelement path="${tempjar-dir}"/>
<pathelement path="${java.class.path}"/>
</path>
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<taskdef name="clientgen"
classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
<target name="build-clientService">
<clientgen
wsdl="http://${wls.hostname}:${wls.port}/async/StockQuote?WSDL"
destDir="${tempjar-dir}"
packageName="examples.webservices.async_req_res"/>
<javac
source="1.5"
srcdir="${tempjar-dir}"
destdir="${tempjar-dir}"
includes="**/*.java"/>
<jwsc
srcdir="src"
destdir="${clientService-ear-dir}"
classpathref="ws.clientService.class.path">
<jws
file="examples/webservices/async_req_res/StockQuoteClientImpl.java" />
</jwsc>
<copy todir="${clientService-ear-dir}/app-inf/classes">
<fileset dir="${tempjar-dir}" />
</copy>
</target>
jwsc
および clientgen
Ant タスクの完全なクラス名を定義するには、taskdef
Ant タスクを使用します。
jwsc
Ant タスクを実行する前に、まず clientgen
を使用して、デプロイされる StockQuote
Web サービスの JAX-RPC スタブを生成およびコンパイルする必要があります。StockQuoteClientImpl
JWS ファイルは生成されたクラスをインポートして使用するので、これらのクラスが既に存在している状態でなければ、jwsc
タスクが失敗するからです。デフォルトでは、clientgen
Ant タスクは JAX-RPC スタブ内に Web サービス オペレーションの同期した種類のものと非同期な種類のものを両方とも生成します。jwsc
Ant タスクを実行する場合、classpathref
属性を使用して、clientgen
がアーティファクトを生成する一時ディレクトリを CLASSPATH に追加します。
jwsc
がすべてのアーティファクトを EAR ディレクトリの中に生成したら、copy
Ant タスクを使用して、clientgen
により生成されたアーティファクトを、EAR の APP-INF/classes
ディレクトリへコピーし、StockQuoteClient
Web サービスがこれらを見つけられるようにします。
注意 : APP-INF/classes
ディレクトリは、エンタープライズ アプリケーション内のクラスを共有するための WebLogic 固有の機能です。
Web サービスと、その Web サービスが呼び出すクライアント アプリケーションは、1 つのタスクを完了するために複数回通信する場合があります。また、複数のクライアント アプリケーションが同時に同じ Web サービスと通信する場合もあります。会話を使用すると、直接的な方法で、呼び出し間のデータを追跡して、Web サービスが常に正しいクライアントに応答するようにできます。
会話を使用すると、複数の通信にわたってデータを維持することに伴う以下の 2 つの問題が解決されます。
WebLogic Server はこのユニークな ID とステートを、クライアント アプリケーションが新しく会話を開始するたびに会話コンテキストを作成することによって管理します。Web サービスがその後、このコンテキストを使用して、サービスとの間の呼び出しを相関させ、ステート関連データを永続化します。
クライアント アプリケーションと Web サービスの間の会話には、明確なフェーズが 3 つあります。
会話は通常、2 つの WebLogic サービス間で発生します。そのうち 1 つは会話形式のものとしてマークされ、開始、続行、および終了のオペレーションを含みます。もう 1 つの Web サービスは @ServiceClient
アノテーションを使用して、それが会話形式の Web サービスのクライアントであることを指定します。また、制限事項はありますが、会話形式の Web サービスはスタンドアロン Java クライアントからも呼び出せます。
他の WebLogic Web サービスの機能と同様に、Web サービスを会話形式のものとして指定するには、JWS アノテーションを使用します。
以下の手順では、会話形式の Web サービス、ならびにクライアント Web サービスおよびスタンドアロン Java クライアント アプリケーション (いずれも会話を開始および実施するもの) を作成する方法について説明します。この手順では、2 つの Web サービスを、何もない状態から実装する JWS ファイルの作成方法を示しています。既存の JWS ファイルを更新する場合は、この手順をガイドとして利用してください。
Ant ベースの開発環境を設定済みであり、かつ jwsc
Ant タスクを実行して、生成された会話形式の Web サービスをデプロイするためのターゲットを追加できる、作業用の build.xml
ファイルがあることが前提となっています。さらに、会話を開始するクライアント Web サービスをホストする、WebLogic Server を同様に設定してあることも前提となっています。詳細については、「一般的な Web サービスの使用例とサンプル」、「WebLogic Web サービスの反復的な開発」、および「JWS ファイルのプログラミング」を参照してください。
「会話形式の JWS ファイルに関するプログラミングのガイドライン」を参照してください。
「jwsc WebLogic Web サービス Ant タスクの実行」を参照してください。
prompt> ant build-mainService
「WebLogic Web サービスのデプロイとアンデプロイ」を参照してください。
「会話形式の Web サービスを呼び出す JWS ファイルに関するプログラミングのガイドライン」を参照してください。
「会話形式の Web サービスのクライアント用 build.xm ファイルの更新」を参照してください。
prompt> ant build-clientService
「WebLogic Web サービスのデプロイとアンデプロイ」を参照してください。
次のサンプルでは、会話形式の Web サービスを実装する簡単な JWS ファイルを示します。太字で示された Java コードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。
package examples.webservices.conversation;
import java.io.Serializable;
import weblogic.jws.WLHttpTransport;import weblogic.jws.Conversation;
import weblogic.jws.Conversational;
import weblogic.jws.Context;
import weblogic.wsee.jws.JwsContext;
import weblogic.wsee.jws.ServiceHandle;
import javax.jws.WebService;
import javax.jws.WebMethod;
@Conversational(maxIdleTime="10 minutes",
maxAge="1 day",
runAsStartUser=false,
singlePrincipal=false )
@WebService(name="ConversationalPortType",
serviceName="ConversationalService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="conv",
serviceUri="ConversationalService",
portName="ConversationalServicePort")
/**
* 会話形式の Web サービス
*/
public class ConversationalServiceImpl implements Serializable {
@Context
public String status = "undefined";
private JwsContext ctx;
@WebMethod@Conversation (Conversation.Phase.START)
public String start() {
ServiceHandle handle = ctx.getService();
String convID = handle.getConversationID();
status = "start";
return "Starting conversation, with ID " + convID + " and status equal to " + status;
}
@WebMethod@Conversation (Conversation.Phase.CONTINUE)
public String middle(String message) {
status = "middle";
return "Middle of conversation; the message is: " + message + " and status is " + status;
}
@WebMethod@Conversation (Conversation.Phase.FINISH)
public String finish(String message ) {
status = "finish";
return "End of conversation; the message is: " + message + " and status is " + status;
}
}
会話形式の Web サービスを実装している JWS ファイルをプログラミングする際には、以下のガイドラインに従います。ガイドラインのコード例は、上述のサンプル内では太字で示されています。
java.io.Serializable
を実装していなければならないので、まず JWS ファイルにクラスをインポートする必要がある。
import java.io.Serializable;
import weblogic.jws.Conversation;
import weblogic.jws.Conversational;
@Context
アノテーションおよびコンテキスト API をインポートする。
import weblogic.jws.Context;
import weblogic.wsee.jws.JwsContext;
import weblogic.wsee.jws.ServiceHandle;
実行時 Web サービスのコンテキストの詳細については、「JwsContext を使用した Web サービスの実行時情報へのアクセス」を参照してください。
@Conversational
アノテーションを使用して、Web サービスを会話形式のものであると指定する。このアノテーションは任意指定ですが (メソッド レベルの @Conversation
アノテーションを指定していると仮定した場合)、常にこれを JWS ファイル内で使用して、Web サービスが会話形式であると明確に指定することをお勧めします。指定する任意の属性は、WebLogic Server が会話を終了するまでの、Web サービスがアイドル状態でいられる最大時間を指定する maxIdleTime
、会話の最大存続期間を指定する maxAge
、既存の会話の続行フェーズと終了フェーズを、会話を開始したユーザとして実行するかどうかを指定する runAsStartUser
、会話を開始したユーザ以外のユーザが、会話の続行フェーズと終了フェーズの実行を許可されるかどうかを指定する singlePrincipal
のうちのいずれかです。
@Conversational(maxIdleTime="10 minutes",
maxAge="1 day",
runAsStartUser=false,
singlePrincipal=false )
JWS ファイルに @Conversational
アノテーションが含まれている場合、Web サービスのすべてのオペレーションが会話形式です。オペレーションのデフォルトのフェーズは、明示的に@Conversaion
アノテーションが指定されていなければ、続行フェーズです。 ただし、会話形式の Web サービスには、1 つ以上の開始オペレーションと、1 つの終了オペレーションが含まれていることが必要なので、メソッド レベルの @Conversation
アノテーションを使用して、これらのオペレーションをどのメソッドで実装するかを指定する必要があります。このサンプルを後に示します。
属性のデフォルト値の詳細については、「weblogic.jws.Conversational」を参照してください。
java.io.Serializable
が実装されている必要がある。
public class ConversationalServiceImpl implements Serializable {
weblogic.wsee.jws.JwsContext
のプライベート クラス変数に、フィールド レベルの @Context
JWS アノテーションを付けます。
@Context
private JwsContext ctx;
@Conversation
アノテーションを使用して、会話の開始、続行、および終了フェーズを実装するメソッドを指定する。会話には、1 つ以上の開始オペレーションと、1 つの終了オペレーションが必要です。続行オペレーションは任意指定です。フェーズを指定するアノテーションには、Conversation.Phase.START
、Conversation.Phase.CONTINUE
、または Conversation.Phase.FINISH
の各パラメータを使用します。次の例では、開始オペレーションを指定しています。
@WebMethod
@Conversation (Conversation.Phase.START)
public String start() {...
@Conversation
アノテーションでマークする JWS ファイルのメソッドが 1 つだけの場合、Web サービス全体が会話形式となり、各オペレーションは、会話の一部と見なされます。これは、JWS ファイルで任意指定のクラス レベル @Conversational
アノテーションを使用していなかった場合でも当てはまります。@Conversational
で明示的にアノテーション付きにされていないメソッドはすべて、デフォルトで続行オペレーションとなります。つまり、たとえばクライアント アプリケーションが、それ以前に開始オペレーションを呼び出していない状態で、これらの続行メソッドの 1 つを呼び出すと、Web サービスが実行時エラーを返すということです。
なお、スタンドアロン Java クライアントから会話形式の Web サービスを呼び出す場合、開始オペレーションは要求と応答であることが必要です。言い換えると、このオペレーションに、@Oneway
JWS アノテーションを付けることはできません。オペレーションは、void
を返すことがあります。Web サービスを、WebLogic Server で実行されているクライアント アプリケーションからのみ呼び出す場合、この要件は適用されません。
詳細については、「weblogic.jws.Conversation」を参照してください。
JwsContext
インスタンスを使用する。たとえば、開始オペレーションの次のコードでは、WebLogic Server が新しい会話に割り当てる ID を取得します。
ServiceHandle handle = ctx.getService();
String convID = handle.getConversationID();
コンテキスト関連の API の使用の詳細については、「JwsContext を使用した Web サービスの実行時情報へのアクセス」を参照してください。
次の例では、「会話形式の JWS ファイルに関するプログラミングのガイドライン」で説明した会話形式の Web サービスを呼び出す Web サービス用の簡単な JWS ファイルを示します。太字で示された Java コードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。
package examples.webservices.conversation;
import weblogic.jws.WLHttpTransport;import weblogic.jws.ServiceClient;
import javax.jws.WebService;
import javax.jws.WebMethod;
import examples.webservices.conversation.ConversationalPortType;
import java.rmi.RemoteException;
@WebService(name="ConversationalClientPortType",
serviceName="ConversationalClientService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="convClient",
serviceUri="ConversationalClient",
portName="ConversationalClientPort")
/**
* ConversationalService と会話を行うクライアント
*/
public class ConversationalClientImpl {
@ServiceClient(
wsdlLocation="http://localhost:7001/conv/ConversationalService?WSDL",
serviceName="ConversationalService",
portName="ConversationalServicePort")
private ConversationalPortType port;
@WebMethod
public void runConversation(String message) {
try {
// 開始オペレーションを呼び出すString result = port.start();
System.out.println("start method executed.");
System.out.println("The message is: " + result);
// 続行オペレーションを呼び出すresult = port.middle(message );
System.out.println("middle method executed.");
System.out.println("The message is: " + result);
// 終了オペレーションを呼び出すresult = port.finish(message );
System.out.println("finish method executed.");
System.out.println("The message is: " + result);
}
catch (RemoteException e) {
e.printStackTrace();
}
}
}
会話形式の Web サービスを呼び出す JWS ファイルをプログラミングする際には、以下のガイドラインに従います。ガイドラインのコード例は、上述のサンプル内では太字で示されています。
@ServiceClient
JWS アノテーションをインポートする。
import weblogic.jws.ServiceClient;
clientgen
Ant タスクによって、後から作成されます。スタブ パッケージは、clientgen
の packageName
属性によって指定され、スタブの名前は呼び出された Web サービスの WSDL によって決まります。
import examples.webservices.conversation.ConversationalPortType;
@ServiceClient
JWS アノテーションを使用して、呼び出し対象の会話形式の Web サービスの WSDL、名前、およびポートを指定する。このアノテーションは、プライベート変数のフィールド レベルで指定します。この変数のデータ型は、呼び出している Web サービスの JAX-RPC ポートの種類となります。
@ServiceClient(
wsdlLocation="http://localhost:7001/conv/ConversationalService?WSDL",
serviceName="ConversationalService",
portName="ConversationalServicePort")
private ConversationalPortType port;
@ServiceClient
アノテーションを付けたスタブを使用して、会話形式の Web サービスの開始オペレーションを呼び出し、会話を開始する。開始メソッドは、JWS ファイルの任意の場所 (コンストラクタ、メソッドなど) から呼び出せます。
String result = port.start();
result = port.middle(message );
result = port.finish(message );
build.xml
ファイルを更新して、会話形式の Web サービスを呼び出す JWS ファイルを生成するには、次のような taskdefs
および build-clientService
ターゲットを追加します。詳細については、サンプルの後の説明を参照してください。
<path id="ws.clientService.class.path">
<pathelement path="${tempjar-dir}"/>
<pathelement path="${java.class.path}"/>
</path>
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<taskdef name="clientgen"
classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
<target name="build-clientService">
<clientgen
wsdl="http://${wls.hostname}:${wls.port}/conv/ConversationalService?WSDL"
destDir="${tempjar-dir}"
packageName="examples.webservices.conversation"/>
<javac
source="1.5"
srcdir="${tempjar-dir}" destdir="${tempjar-dir}"
includes="**/*.java"/>
<jwsc
srcdir="src"
destdir="${clientService-ear-dir}"
classpathref="ws.clientService.class.path">
<jws
file="examples/webservices/conversation/ConversationalClientImpl.java"
/>
</jwsc>
<copy todir="${clientService-ear-dir}/APP-INF/classes">
<fileset dir="${tempjar-dir}" />
</copy>
</target>
jwsc
および clientgen
Ant タスクの完全なクラス名を定義するには、taskdef
Ant タスクを使用します。
jwsc
Ant タスクを実行する前に、まず clientgen
を使用して、デプロイされる ConversationalService
Web サービスの JAX-RPC スタブを生成およびコンパイルする必要があります。ConversationalClientImpl
JWS ファイルは生成されたクラスをインポートして使用するので、これらのクラスが既に存在している状態でなければ、jwsc
タスクが失敗するからです。jwsc
Ant タスクを実行する場合、classpathref
属性を使用して、clientgen
がアーティファクトを生成する一時ディレクトリを CLASSPATH に追加します。
jwsc
がすべてのアーティファクトを EAR ディレクトリの中に生成したら、copy
Ant タスクを使用して、clientgen
により生成されたアーティファクトを、EAR の APP-INF/classes
ディレクトリへコピーし、ConversationalClientService
Web サービスがこれらを見つけられるようにします。
注意 : APP-INF/classes
ディレクトリは、エンタープライズ アプリケーション内のクラスを共有するための WebLogic 固有の機能です。
次の例では、「会話形式の JWS ファイルに関するプログラミングのガイドライン」で説明した会話形式の Web サービスを呼び出すための簡単なスタンドアロン Java クライアントを示します。太字で示された Java コードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。
package examples.webservices.conv_standalone.client;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.Stub;
import weblogic.wsee.jaxrpc.WLStub;
/**
* ConversationlService を呼び出し、これと会話するスタンドアロン クライアント
*/
public class Main {
public static void main(String[] args)
throws ServiceException, RemoteException{
ConversationalService service = new ConversationalService_Impl(args[0] + "?WSDL");
ConversationalPortType port = service.getConversationalServicePort();
// スタブ上のプロパティを設定して、クライアントが高度な機能を使用する Web
// サービスを呼び出していることを指定する。このプロパティは、クライアントが
// WebLogic Server インスタンスで実行されている場合には自動的に設定される
Stub stub = (Stub)port;
stub._setProperty(WLStub.COMPLEX, "true");
// 開始オペレーションを呼び出して会話を開始するString result = port.start();
System.out.println("start method executed.");
System.out.println("The message is: " + result);
// 続行オペレーションを呼び出すresult = port.middle("middle" );
System.out.println("middle method executed.");
System.out.println("The message is: " + result);
// 終了オペレーションを呼び出すresult = port.finish("finish" );
System.out.println("finish method executed.");
System.out.println("The message is: " + result);
}
}
会話形式の Web サービスを呼び出すスタンドアロン Java クライアントをプログラミングする際には、以下のガイドラインに従います。ガイドラインのコード例は、上述のサンプル内では太字で示されています。
weblogic.wsee.jaxrpc.WLStub
クラスをインポートする。
import weblogic.wsee.jaxrpc.WLStub;
Stub stub = (Stub)port;
stub._setProperty(WLStub.COMPLEX, "true");
このプロパティは、クライアントが高度な Web サービス (この場合は会話形式の Web サービス) を呼び出すことを Web サービスのランタイムに対して指定します。このプロパティは、別の WebLogic Web サービスから会話形式の Web サービスを呼び出している場合には、自動的に設定されます。
String result = port.start();
result = port.middle(message );
result = port.finish(message );
バッファ付きオペレーションがクライアントによって呼び出されると、メソッド オペレーションは JMS キューに渡され、WebLogic Server は非同期にそれを処理します。Web サービスの信頼性のあるメッセージングの場合と同様に、メソッド呼び出しがまだキューに入っているときに WebLogic Server が停止しても、再起動すればすぐに処理が行われます。バッファ付きオペレーションは一方向のものなので、バッファ付き Web サービスを呼び出すクライアントが呼び出しからの応答を待機しないまま、クライアントの実行が続行可能です。
以下の手順では、バッファ付き Web サービスと、そのバッファ付き Web サービスのオペレーションを呼び出すクライアント Web サービスを作成する方法を説明しています。この手順では、2 つの Web サービスを、何もない状態から実装する JWS ファイルの作成方法を示しています。既存の JWS ファイルを更新する場合は、この手順をガイドとして利用してください。この手順ではまた、バッファ付き Web サービスをホストする WebLogic Server インスタンスをコンフィグレーションする方法も示しています。
注意 : 非同期の要求と応答機能を一緒に使用しているのでなければ、別の Web サービスからバッファ付き Web サービスを呼び出す必要はありません。これは、スタンドアロン Java アプリケーションからも呼び出すことができます。
Ant ベースの開発環境を設定済みであり、かつ jwsc
Ant タスクを実行して、生成されたバッファ付き Web サービスをデプロイするためのターゲットを追加できる、作業用の build.xml
ファイルがあることが前提となっています。さらに、バッファ付き Web サービスを呼び出すクライアント Web サービスをホストする、WebLogic Server を同様に設定してあることも前提となっています。詳細については、以下を参照してください。
「バッファ付き JWS ファイルに関するプログラミングのガイドライン」を参照してください。
<jwsc
srcdir="src"
destdir="${service-ear-dir}" >
<jws
file="examples/webservices/async_buffered/AsyncBufferedImpl.java"
/>
</jwsc>
jwsc
タスクの使用に関する全般的な情報については、「jwsc WebLogic Web サービス Ant タスクの実行」を参照してください。
prompt> ant build-mainService deploy-mainService
「バッファ付き Web サービスを呼び出す JWS ファイルのプログラミング」を参照してください。
「バッファ付き Web サービスのクライアント用 build.xm ファイルの更新」を参照してください。
prompt> ant build-clientService deploy-clientService
バッファ付き Web サービスのデプロイ先となる WebLogic Server インスタンスをコンフィグレーションする際には、Web サービスのランタイムで内部的に使用される、JMS サーバやモジュールなどの JMS リソースがコンフィグレーションされます。以下の高度な手順では、タスクを列挙し、その後それらのタスクを実行するにあたっての詳細が記載された Administration Console オンライン ヘルプを示します。
Administration Console を起動する URL に関する手順については、「Administration Console の起動」を参照してください。
「JMS サーバの作成」を参照してください。
バッファ付き Web サービスで、デフォルト Web サービスのキューを使用する場合は、JMS キューの JNDI 名を weblogic.wsee.DefaultQueue
に設定します。そうせずに、別の JNDI 名を使用する場合は、必ず後述する @BufferQueue
アノテーションを使って、この JNDI 名をバッファ付き Web サービスに対して指定します。
バッファ付き Web サービスの機能をクラスタ内で使用している場合は、分散キューではなく、ローカル キューを作成する必要があります。加えて、このキューを明示的にクラスタ内の各サーバに割り当てる必要があります。
「JMS システム モジュールの作成」および「キューの作成」を参照してください。
次のサンプルでは、会話形式の Web サービスを実装する簡単な JWS ファイルを示します。太字で示された Java コードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。
package examples.webservices.buffered;
import javax.jws.WebMethod;
import javax.jws.WebService;import javax.jws.Oneway;
import weblogic.jws.WLHttpTransport;import weblogic.jws.MessageBuffer;
import weblogic.jws.BufferQueue;
@WebService(name="BufferedPortType",
serviceName="BufferedService",
targetNamespace="http://example.org")
@WLHttpTransport(contextPath="buffered",
serviceUri="BufferedService",
portName="BufferedPort")
// デフォルトではなく特定の JMS キューを指定するアノテーション
@BufferQueue(name="my.jms.queue")
/**
* 簡単なバッファ付き Web サービス
*/
public class BufferedImpl {
@WebMethod()@MessageBuffer(retryCount=10, retryDelay="10 seconds")
@Oneway()
public void sayHelloNoReturn(String message) {
System.out.println("sayHelloNoReturn: " + message);
}
}
バッファ付き Web サービスを実装している JWS ファイルをプログラミングする際には、以下のガイドラインに従います。ガイドラインのコード例は、上述のサンプル内では太字で示されています。
import javax.jws.Oneway;
import weblogic.jws.MessageBuffer;
import weblogic.jws.BufferQueue;
@BufferQueue
JWS アノテーションを使用し、バッファ付きの呼び出しを処理する際に WebLogic Server によって内部使用される JMS キューの JNDI 名を指定する。たとえば、次のようになります。
@BufferQueue(name="my.jms.queue")
この JWS アノテーションを指定しなかった場合、WebLogic Server は、デフォルト Web サービス JMS キュー (weblogic.wsee.DefaultQueue
) を使用します。
デフォルトの JMS キューと、このアノテーションで指定されたキューの双方を作成してからでなければ、バッファ付きのオペレーションを正常に呼び出すことはできません。詳細については、「バッファ付き Web サービスをホストする WebLogic Server のコンフィグレーション」を参照してください。
@MessageBuffer
JWS アノテーションを使用し、バッファリングされた Web サービスのオペレーションを指定する。アノテーションには、次の 2 つの任意指定の属性があります。retryCount
: WebLogic Server による JMS キューから Web サービス実装へのメッセージ配信試行回数 (デフォルトでは 3)。retryDelay
: サーバが待機すべき再試行間隔 (デフォルトでは 5 分)。
@MessageBuffer(retryCount=10, retryDelay="10 seconds")
このアノテーションをクラス レベルで使用すると、すべてのオペレーションをバッファ付きにすることを指定でき、メソッド レベルで指定すると、どのオペレーションをバッファ付きにするかを選択できます。
@OneWay
JWS アノテーションを使用して、バッファ付きオペレーションが、一方向にのみ呼び出せることを指定する。このアノテーションには属性はありません。この JWS アノテーションでアノテーション付きにされたメソッドは、値を返せません。つまり、void
を返すことになります。たとえば、次のようになります。
@Oneway()
public void sayHelloNoReturn(String message) {
注意 : バッファ付き Web サービスで非同期の要求と応答を使用している場合は、この JWS アノテーションを指定する必要はないので、メソッドは値を返すことができます。「非同期機能の併用」を参照してください。
バッファ付き Web サービスは、スタンドアロン Java アプリケーション (非同期の要求と応答を使用していない場合) と、別の Web サービスの、双方から呼び出せます。ただし、他の WebLogic Web サービスの非同期機能とは異なり、クライアント Web サービスにおいて @ServiceClient
JWS アノテーションは使用せず、その他のサービスと同じように呼び出します。詳細については、「別の Web サービスからの Web サービスの呼び出し」を参照してください。
次のサンプル JWS ファイルでは、BufferedService
Web サービスの sayHelloNoReturn
オペレーションを呼び出す方法を示します。
package examples.webservices.buffered;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import javax.jws.WebService;
import javax.jws.WebMethod;
import weblogic.jws.WLHttpTransport;
import examples.webservices.buffered.BufferedPortType;
import examples.webservices.buffered.BufferedService_Impl;
import examples.webservices.buffered.BufferedService;
@WebService(name="BufferedClientPortType",
serviceName="BufferedClientService",
targetNamespace="http://examples.org")
@WLHttpTransport(contextPath="bufferedClient",
serviceUri="BufferedClientService",
portName="BufferedClientPort")
public class BufferedClientImpl {
@WebMethod()
public String callBufferedService(String input, String serviceUrl)
throws RemoteException {
try {
BufferedService service = new BufferedService_Impl(serviceUrl + "?WSDL");
BufferedPortType port = service.getBufferedPort();
// BufferedService の sayHelloNoReturn() オペレーションを呼び出す
port.sayHelloNoReturn(input);
return "Invoke went okay!";
} catch (ServiceException se) {
System.out.println("ServiceExcpetion thrown");
throw new RuntimeException(se);
}
}
}
build.xml
ファイルを更新して、バッファ付き Web サービスのオペレーションを呼び出す JWS ファイルを生成するには、次のような taskdefs
および build-clientService
ターゲットを追加します。詳細については、サンプルの後の説明を参照してください。
<path id="ws.clientService.class.path">
<pathelement path="${tempjar-dir}"/>
<pathelement path="${java.class.path}"/>
</path>
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<taskdef name="clientgen"
classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
<target name="build-clientService">
<clientgen
wsdl="http://${wls.hostname}:${wls.port}/buffered/BufferedService?WSDL"
destDir="${tempjar-dir}"
packageName="examples.webservices.buffered"/>
<javac
source="1.5"
srcdir="${tempjar-dir}"
destdir="${tempjar-dir}"
includes="**/*.java"/>
<jwsc
srcdir="src"
destdir="${clientService-ear-dir}"
classpathref="ws.clientService.class.path">
<jws
file="examples/webservices/buffered/BufferedClientImpl.java"
/>
</jwsc>
<copy todir="${clientService-ear-dir}/app-inf/classes">
<fileset dir="${tempjar-dir}" />
</copy>
</target>
jwsc
および clientgen
Ant タスクの完全なクラス名を定義するには、taskdef
Ant タスクを使用します。
jwsc
Ant タスクを実行する前に、まず clientgen
を使用して、デプロイされる BufferedService
Web サービスの JAX-RPC スタブを生成およびコンパイルする必要があります。BufferedClientImpl
JWS ファイルは生成されたクラスの 1 つをインポートして使用するので、これらのクラスが既に存在している状態でなければ、jwsc
タスクが失敗するからです。jwsc
Ant タスクを実行する場合、classpathref
属性を使用して、clientgen
がアーティファクトを生成する一時ディレクトリを CLASSPATH に追加します。
jwsc
がすべてのアーティファクトを EAR ディレクトリの中に生成したら、copy
Ant タスクを使用して、clientgen
により生成されたアーティファクトを、EAR の APP-INF/classes
ディレクトリへコピーし、BufferedClientService
Web サービスがこれらを見つけられるようにします。
注意 : APP-INF/classes
ディレクトリは、エンタープライズ アプリケーション内のクラスを共有するための WebLogic 固有の機能です。
ここまでの各節では、WebLogic Web サービスの非同期機能 (Web サービスの信頼性のあるメッセージング、会話、非同期の要求と応答、およびバッファリング) を単独で使用する方法を説明してきました。しかし通常、Web サービスではこれらの機能を、併用しています。例については、「信頼性のある会話形式の Web サービスを実装する JWS ファイルの例」および「信頼性のある会話形式の Web サービスを非同期で呼び出すクライアント Web サービスの例」を参照してください。
併用すると、個々の機能についての節で説明した制限事項の一部が適用されなくなったり、場合によっては追加の制限事項が適用されたりします。以下で、併用する機能ごとに説明します。
void
を返す必要がありません。@ServiceClient
JWS アノテーションを使用する必要があります。 AsyncPreCallContext
または AsyncPostCallContext
) にプロパティを設定する場合、そのプロパティは、java.io.Serializable
を実装している必要があります。WLStub.CONVERSATIONAL_METHOD_BLOCK_TIMEOUT
を設定する場合、クライアントはブロックを行わないので、プロパティは無視されます。@Oneway
アノテーションでマークされていないものである必要があります。WebServiceA
が会話形式であり、これが非同期の要求と応答を使用して WebServiceB
を呼び出すとします。WebServiceA
が会話形式なので、WebServiceB
からの非同期応答もまた、同じ会話に参加することになります。次のサンプルの JWS ファイルでは、信頼性があり、かつ会話形式でもある Web サービスを実装しています。
package examples.webservices.async_mega;
import java.io.Serializable;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.Conversation;
import weblogic.jws.Policy;
import javax.jws.WebService;
import javax.jws.WebMethod;
@WebService(name="AsyncMegaPortType",
serviceName="AsyncMegaService",
targetNamespace="http://examples.org/")
@Policy(uri="AsyncReliableConversationPolicy.xml",
attachToWsdl=true)
@WLHttpTransport(contextPath="asyncMega",
serviceUri="AsyncMegaService",
portName="AsyncMegaServicePort")
/**
* 信頼性があり、かつ会話形式でもある Web サービス
*/
public class AsyncMegaServiceImpl implements Serializable {
@WebMethod
@Conversation (Conversation.Phase.START)
public String start() {
return "Starting conversation";
}
@WebMethod
@Conversation (Conversation.Phase.CONTINUE)
public String middle(String message) {
return "Middle of conversation; the message is: " + message;
}
@WebMethod
@Conversation (Conversation.Phase.FINISH)
public String finish(String message ) {
return "End of conversation; the message is: " + message;
}
}
次の JWS ファイルでは、「信頼性のある会話形式の Web サービスを実装する JWS ファイルの例」に記載の Web サービスにおけるさまざまな会話形式のメソッドを確実に呼び出すクライアント Web サービスの実装方法を示します。クライアント JWS ファイルでは、非同期の要求と応答機能も使用しています。
package examples.webservices.async_mega;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.ServiceClient;
import weblogic.jws.AsyncResponse;
import weblogic.jws.AsyncFailure;
import javax.jws.WebService;
import javax.jws.WebMethod;
import weblogic.wsee.async.AsyncPreCallContext;
import weblogic.wsee.async.AsyncCallContextFactory;
import weblogic.wsee.async.AsyncPostCallContext;
import examples.webservices.async_mega.AsyncMegaPortType;
import examples.webservices.async_mega.AsyncMegaService;
import examples.webservices.async_mega.AsyncMegaService_Impl;
import java.rmi.RemoteException;
@WebService(name="AsyncMegaClientPortType",
serviceName="AsyncMegaClientService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="asyncMegaClient",
serviceUri="AsyncMegaClient",
portName="AsyncMegaClientServicePort")
/**
* AsyncMegaService との間で信頼性を伴い非同期に会話するクライアント
* Web サービス
*/
public class AsyncMegaClientImpl {
@ServiceClient(
wsdlLocation="http://localhost:7001/asyncMega/AsyncMegaService?WSDL",
serviceName="AsyncMegaService",
portName="AsyncMegaServicePort")
private AsyncMegaPortType port;
@WebMethod
public void runAsyncReliableConversation(String message) {
AsyncPreCallContext apc = AsyncCallContextFactory.getAsyncPreCallContext();
apc.setProperty("message", message);
try {
port.startAsync(apc);
System.out.println("start method executed.");
port.middleAsync(apc, message );
System.out.println("middle method executed.");
port.finishAsync(apc, message );
System.out.println("finish method executed.");
}
catch (RemoteException e) {
e.printStackTrace();
}
}
@AsyncResponse(target="port", operation="start")
public void onStartAsyncResponse(AsyncPostCallContext apc, String message) {
System.out.println("-------------------");
System.out.println("Got message " + message );
System.out.println("-------------------");
}
@AsyncResponse(target="port", operation="middle")
public void onMiddleAsyncResponse(AsyncPostCallContext apc, String message) {
System.out.println("-------------------");
System.out.println("Got message " + message );
System.out.println("-------------------");
}
@AsyncResponse(target="port", operation="finish")
public void onFinishAsyncResponse(AsyncPostCallContext apc, String message) {
System.out.println("-------------------");
System.out.println("Got message " + message );
System.out.println("-------------------");
}
@AsyncFailure(target="port", operation="start")
public void onStartAsyncFailure(AsyncPostCallContext apc, Throwable e) {
System.out.println("-------------------");
e.printStackTrace();
System.out.println("-------------------");
}
@AsyncFailure(target="port", operation="middle")
public void onMiddleAsyncFailure(AsyncPostCallContext apc, Throwable e) {
System.out.println("-------------------");
e.printStackTrace();
System.out.println("-------------------");
}
@AsyncFailure(target="port", operation="finish")
public void onFinishAsyncFailure(AsyncPostCallContext apc, Throwable e) {
System.out.println("-------------------");
e.printStackTrace();
System.out.println("-------------------");
}
}
信頼性のある Web サービスを呼び出すクライアント アプリケーション、または非同期の要求応答を使用するクライアント アプリケーションでは、オペレーションを直接呼び出さず、プロキシ サーバを使用する場合があります。プロキシを使用する理由としては、ファイアウォールの存在や、呼び出された Web サービスがクラスタにデプロイされていることなどが挙げられます。
この場合、呼び出された Web サービスをホストする WebLogic Server インスタンスは、プロキシ サーバのアドレスとポートでコンフィグレーションされる必要があります。Web サービスがクラスタにデプロイされている場合は、そのクラスタ内のすべてのサーバをコンフィグレーションすることが必要です。
weblogic-wsee-proxy-channel-
XXX
とする必要があります。XXX
は、プロトコルを表します。たとえば、HTTPS 用のネットワーク チャネルを作成する場合、weblogic-wsee-proxy-channel-https
という名前にします。 ネットワーク チャネルの作成に関する全般的な情報については、「カスタム ネットワーク チャネルのコンフィグレーション」を参照してください。
通常、クライアント アプリケーションから WebLogic Web サービスを呼び出すときは、接続プロトコルとして HTTP/S が使用されます。しかし、アプリケーションが転送に JMS を使用するように WebLogic Web サービスをコンフィグレーションすることもできます。JWS アノテーションか、後の節で説明する jwsc
Ant タスクの子要素のどちらかを使用して、転送をコンフィグレーションします。
WebLogic Web サービスで、接続転送に JMS を使用するようにコンフィグレーションを行った場合、Web サービスの WSDL で生成された対応するポートに対して指定されたエンドポイント アドレスの URL では、http://
ではなく jms://
が使用されます。JMS エンドポイントのアドレスの例を次に示します。
jms://myHost:7001/transports/JMSTransport?URI=JMSTransportQueue
URL の URI=JMSTransportQueue
セクションでは、JMS 転送機能用にコンフィグレーションされた JMS キューを指定しています。HTTP を使用して Web サービスを呼び出すことはできませんが、HTTP を使用してその Web サービスの WSDL を参照することはできます。それにより、clientgen
はやはり Web サービスの JAX-RPC スタブを生成することができます。
指定する各転送に対し、WebLogic Server は WSDL 内に追加のポートを生成します。このため、Web サービス呼び出し時に使用できる転送 (JMS、HTTP、または HTTPS) をクライアント アプリケーションで選択できるようにするには、適切な JWS アノテーションまたは jwsc
の子要素を使用して、明示的に転送を追加する必要があります。
警告 : JMS 転送の使用は、WebLogic の付加価値機能です。.NET クライアントなど、WebLogic 以外のクライアント アプリケーションでは、JMS ポートを使用して Web サービスを呼び出すことはできない場合があります。
次の手順では、JMS 転送を使用して Web サービスを呼び出せることを指定する方法を説明します。
Web サービスを実装する基本的な JWS ファイルを既に作成済みであり、Web サービスが JMS を使用して呼び出されるものとコンフィグレーションすることが前提となっています。また、Ant ベースの開発環境を設定済みであり、かつ jwsc
Ant タスクを実行して、サービスをデプロイするためのターゲットを含む、作業用の build.xml
ファイルがあることが前提となっています。詳細については、「WebLogic Web サービスの反復的な開発」および「JWS ファイルのプログラミング」を参照してください。
「JMS サーバの作成」を参照してください。
「JMS システム モジュールの作成」を参照してください。
weblogic.wsee.DefaultQueue
) を指定することも、別の名前を指定することもできます。別の JNDI 名を指定する場合は、後でこの名前を Web サービス自体に渡します。「キューの作成」を参照してください。
「@WLJmsTransport JWS アノテーションの使用」を参照してください。
詳細については、「jwsc Ant タスクの <WLJmsTransport> 子要素の使用」を参照してください。
JMS 転送を使用した Web サービスを呼び出すためのクライアント アプリケーションの更新については、「JMS 転送を使用した WebLogic Web サービスの呼び出し」を参照してください。
JWS ファイルをプログラムした時点で、Web サービスの呼び出しにクライアント アプリケーションで (HTTP/S ではなく) JMS 転送を使用することが決まっている場合は、@WLJmsTransport
を使用してその呼び出しの詳細を指定できます。後のビルド時に、「jwsc Ant タスクの <WLJmsTransport> 子要素の使用」に従い、jwsc
Ant タスクの <WLJmsTransport>
子要素を指定して、JWS ファイル内の指定をオーバーライドし、さらなる JMS 転送指定を追加できます。
@WLJmsTranport
アノテーションを使用する際は、以下のガイドラインに従ってください。
@WLJmsTranport
アノテーションは 1 つのみ。 @WLJmsTransport
アノテーションを指定した場合、他の転送アノテーション (@WLHttpTransport
または @WLHttpsTransport
) を指定することはできない。queue
属性を使用する。デフォルトの Web サービス キュー (weblogic.wsee.DefaultQueue
) を使用する場合は、queue
属性を指定する必要はありません。次の例では、@WLJmsTransport
アノテーションを使用する簡単な JWS ファイルを示します。関連するコードは太字で示しています。
package examples.webservices.jmstransport;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import weblogic.jws.WLJmsTransport;
@WebService(name="JMSTransportPortType",
serviceName="JMSTransportService",
targetNamespace="http://example.org")
@SOAPBinding(style=SOAPBinding.Style.DOCUMENT,
use=SOAPBinding.Use.LITERAL,
parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
// Web サービスの URI を構成するのに使用されるコンテキスト パスとサービス URI が
// 「transports/JMSTransport」であることを指定する、WebLogic 固有の
// JWS アノテーション
@WLJmsTransport(contextPath="transports", serviceUri="JMSTransport",
queue="JMSTransportQueue", portName="JMSTransportServicePort")
/**
* この JWS ファイルでは、1 つのオペレーション sayHello を含む簡単な
* Java クラス実装の WebLogic Web サービスを形成する
*
* @author Copyright (c) 2005 by BEA Systems.All rights reserved.
*/
public class JMSTransportImpl {
@WebMethod()
public String sayHello(String message) {
System.out.println("sayHello:" + message);
return "Here is the message: '" + message + "'";
}
}
JMS 転送は jwsc
Ant タスクの <jws>
要素の <WLJmsTransport>
子要素を使用して、ビルド時にも指定できます。ビルド時に転送を指定する理由としては、次のようなものが挙げられます。
@WLXXXTransport
アノテーションが含まれておらず、そのためデフォルトでは HTTP 転送が使用されているが、ビルド時に JMS 転送を使用して Web サービスを呼び出すと決定した。jwsc
Ant タスクに対して転送を指定すると、それが JWS ファイル内のすべての転送アノテーションに優先されます。
次の例では、jwsc
Ant タスクに対して転送を指定する方法を示します。
<target name="build-service">
<jwsc
srcdir="src"
destdir="${ear-dir}">
<jws file="examples/webservices/jmstransport/JMSTransportImpl.java">
<WLJmsTransport
contextPath="transports"
serviceUri="JMSTransport"
portName="JMSTransportServicePort"
queue="JMSTransportQueue"/>
</jws>
</jwsc>
</target>
上述の例では、「@WLJmsTransport JWS アノテーションの使用」に示した JWS ファイルで指定されたものと同じ値を URL および JWS キューに対して指定する方法を示します。
jwsc
Ant タスクの使用の詳細については、「jwsc」を参照してください。
JMS 転送を使用して Web サービスを呼び出すクライアント アプリケーションの記述は、HTTP 転送を使用する場合の記述と同様に行います。ただ 1 つ異なるのは、必ず、JMS キュー (@WLJmsTransport
アノテーションまたは jwsc
Ant タスクの <WLJmsTransport>
子要素で指定) やその他の JMS オブジェクトが作成済みでなければならないという点です。詳細については、「JMS 転送の使用 : 主な手順」を参照してください。
HTTP を使用して JMS 転送でコンフィグレーションされた Web サービスを呼び出すことはできませんが、HTTP を使用してその Web サービスの WSDL を参照することはできます。それにより、clientgen
Ant タスクはやはり Web サービスの JAX-RPC スタブを作成することができます。たとえば、この節で示す Web サービスの WSDL のための URL は、次のようになります。
http://host:port/transports/JMSTransport?WSDL
ただし、デプロイされた Web サービスの WSDL におけるエンドポイント アドレスでは、http://
ではなく jms://
が使用され、このアドレスには修飾子 ?URI=
JMS_QUEUE
が含まれるため、clientgen
Ant タスクは Web サービス呼び出し時に JMS 転送を使用するために必要なスタブを自動作成し、クライアント アプリケーション側で通常と違う処理を行う必要はありません。JMS エンドポイントのアドレスの例を次に示します。
jms://host:port/transports/JMSTransport?URI=JMSTransportQueue
Web サービス呼び出しに関する全般的な情報については、「Web サービスの呼び出し」を参照してください。
Web サービスの中には、SOAP メッセージへのアクセスを必要とするものがあり、SOAP メッセージに対して SOAP メッセージ ハンドラを作成できます。
SOAP メッセージ ハンドラは、Web サービスのリクエストと応答の両方で SOAP メッセージをインターセプトするメカニズムです。ハンドラは、Web サービスそのものと Web サービスを呼び出すクライアント アプリケーションの両方で作成することができます。
ハンドラ使用の簡単な例としては、SOAP メッセージのヘッダ部分の情報へのアクセスがあります。SOAP のヘッダを使用して Web サービス固有の情報を格納しておいて、ハンドラを使用してその情報を操作することができます。
SOAP メッセージ ハンドラは、Web サービスのパフォーマンスを向上させるために使用することもできます。Web サービスがデプロイされてしばらくすると、同じパラメータを使用して Web サービスを呼び出すコンシューマが多いことに気付く場合があります。よく使用される Web サービス呼び出しの結果 (静的な結果を前提として) をキャッシュしておき、Web サービスを実装するバックエンド コンポーネントを呼び出すことなく、適宜、キャッシュしておいた結果をただちに返すことによって、Web サービスのパフォーマンスを向上させることができます。このパフォーマンスの向上は、ハンドラを使用して、SOAP リクエスト メッセージに頻繁に使用されるパラメータが含まれていないかチェックすることで達成されます。
次の表では、Web サービスでハンドラ チェーンがコンフィグレーションされていることを指定するために JWS ファイル内で使用できる標準的な JWS アノテーションを示しています。その後の節で、これらのアノテーションの使い方について、より詳細に説明します。詳細については、Web Services MetaData for the Java Platform 仕様 (JSR-181) を参照してください。
次の表では、javax.xml.rpc.handler
API のメイン クラスおよびインタフェースについて説明します。これらの一部は、ハンドラそのものの作成時に使用します。これらの API については、後の節でより詳細に説明します。これらの API の詳細については、JAX-RPC 1.1 仕様を参照してください。
次の手順では、Web サービスに SOAP メッセージ ハンドラを追加する高度な手順を説明します。
Web サービスを実装する基本的な JWS ファイルを既に作成済みであり、SOAP メッセージ ハンドラおよびハンドラ チェーンを追加することで Web サービスを更新することが前提となっています。また、Ant ベースの開発環境を設定済みであり、かつ jwsc
Ant タスクを実行するためのターゲットを含む、作業用の build.xml
ファイルがあることが前提となっています。詳細については、「WebLogic Web サービスの反復的な開発」および「JWS ファイルのプログラミング」を参照してください。
「SOAP メッセージ ハンドラおよびハンドラ チェーンの設計」を参照してください。
「GenericHandler クラスの作成」を参照してください。
「JWS ファイルでのハンドラのコンフィグレーション」を参照してください。
「ハンドラ チェーン コンフィグレーション ファイルの作成」を参照してください。
「Web サービスのコンパイルと再ビルド」を参照してください。
クライアント サイドの SOAP メッセージ ハンドラおよびハンドラ チェーンの作成については、「クライアントサイド SOAP メッセージ ハンドラの作成と使用」を参照してください。
SOAP メッセージ ハンドラおよびハンドラ チェーンを設計するときには、以下の事項を決める必要があります。
ハンドラ チェーン内の各ハンドラには、SOAP のリクエスト メッセージを処理するメソッドと SOAP の応答メッセージを処理するメソッドが 1 つずつあります。順序付けされたハンドラのグループが、ハンドラ チェーンです。Web サービスに、@HandlerChain
または @SOAPMessageHandler
という 2 つの JWS アノテーションのうち 1 つを備えるハンドラ チェーンが付加されていることを指定します。どちらをいつ使用するかは、後の節で説明します。
Web サービスを呼び出すときに、WebLogic Server は次のようにハンドラを実行します。
handleRequest()
メソッドはすべて、JWS アノテーションで指定されている順序で実行されます。これらの handleRequest()
メソッドのいずれもが、SOAP のリクエスト メッセージを変更できます。handleRequest()
メソッドが実行されると、WebLogic Server は、Web サービスを実装するバックエンド コンポーネントを呼び出し、最終的な SOAP のリクエスト メッセージを渡します。 たとえば、JWS ファイルで @HandlerChain
JWS アノテーションを使用して外部コンフィグレーション ファイルを指定することになっており、そのコンフィグレーション ファイルでは、次の例に示す 3 つのハンドラが格納された SimpleChain
というハンドラ チェーンを定義していると仮定します。
<jwshc:handler-config xmlns:jwshc="http://www.bea.com/xml/ns/jws"
xmlns:soap1="http://HandlerInfo.org/Server1"
xmlns:soap2="http://HandlerInfo.org/Server2"
xmlns="http://java.sun.com/xml/ns/j2ee" >
<jwshc:handler-chain>
<jwshc:handler-chain-name>SimpleChain</jwshc:handler-chain-name>
<jwshc:handler>
<handler-name>handlerOne</handler-name>
<handler-class>examples.webservices.soap_handlers.global_handler.ServerHandler1</handler-class>
</jwshc:handler>
<jwshc:handler>
<handler-name>handlerTwo</handler-name>
<handler-class>examples.webservices.soap_handlers.global_handler.ServerHandler2</handler-class>
</jwshc:handler>
<jwshc:handler>
<handler-name>handlerThree</handler-name>
<handler-class>examples.webservices.soap_handlers.global_handler.ServerHandler3</handler-class>
</jwshc:handler>
</jwshc:handler-chain>
</jwshc:handler-config>
次の図は、WebLogic Server で各ハンドラの handleRequest()
メソッドと handleResponse()
メソッドが実行される順序を示しています。
通常、SOAP のリクエスト メッセージと応答メッセージの両方で同じタイプの処理が必要となるので、各 SOAP メッセージ ハンドラには、それぞれを処理する別個のメソッドがあります。たとえば、SOAP リクエストにあるセキュア データを復号化する handleRequest()
メソッドと、SOAP 応答を暗号化する handleResponse()
メソッドを持つ暗号化ハンドラを設計する場合があります。
一方、SOAP リクエストのみを処理し、それと同等の応答処理は行わないハンドラを設計することもできます。
また、ハンドラ チェーン内の次のハンドラを呼び出さず、そのまま、任意の時点でクライアント アプリケーションに応答を送信することも可能です。その方法は、以下の節で説明します。
SOAP メッセージ ハンドラでは、javax.rpc.xml.handler.GenericHandler
抽象クラスを拡張する必要があります。この抽象クラス自体が、javax.rpc.xml.handler.Handler
インタフェースを実装します。
GenericHandler
クラスは、ハンドラの記述を容易にする便利な抽象クラスです。このクラスは、ライフサイクル メソッド init()
および destroy()
ならびに Handler
インタフェースのさまざまな handleXXX()
メソッドのデフォルト実装を提供します。ハンドラ クラスを記述する際には、Handler
実装クラスの一部としてカスタマイズが必要なメソッドのみをオーバーライドします。
具体的には、Handler インタフェースには、GenericHandler
を拡張するハンドラ クラス内で実装できる、次のメソッドが格納されています。
init()
「Handler.init() メソッドを実装する」を参照してください。
destroy()
「Handler.destroy() メソッドを実装する」を参照してください。
getHeaders()
「Handler.getHeaders() メソッドを実装する」を参照してください。
handleRequest()
「Handler.handleRequest() メソッドを実装する」を参照してください。
handleResponse()
「Handler.handleResponse() メソッドを実装する」を参照してください。
handleFault()
「Handler.handleFault() メソッドを実装する」を参照してください。
特に画像などの添付ファイルを処理する場合などには、ハンドラ内から直接 SOAP メッセージを表示または更新しなければならない場合もあります。その場合には、javax.xml.soap.SOAPMessage
抽象クラスを使用します。このクラスは、SOAP With Attachments API for Java 1.1 (SAAJ) 仕様の構成要素です。詳細については、「SAAJ を使用した SOAP リクエスト メッセージおよび応答メッセージの直接操作」を参照してください。
次の例は、SOAP のリクエストおよび応答メッセージを WebLogic Server のログ ファイルに出力する簡単な SOAP メッセージ ハンドラを示しています。
package examples.webservices.soap_handlers.global_handler;
import javax.xml.namespace.QName;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.GenericHandler;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.rpc.JAXRPCException;
import weblogic.logging.NonCatalogLogger;
/**
* このクラスは、SOAP のリクエストおよび応答メッセージにアクセスするために使用する、ハンドラ チェーンの
* ハンドラを実装する
* <p>
* このクラスは、<code>javax.xml.rpc.handler.GenericHandler</code> 抽象クラスを
* 拡張するものであり、単に、メッセージが Web サービス自体を実装するバックエンド
* Java クラスによって処理される前に、SOAP リクエストおよび応答メッセージを
* サーバ ログ ファイルに出力する
*/
public class ServerHandler1 extends GenericHandler {
private NonCatalogLogger log;
private HandlerInfo handlerInfo;
/**
* ハンドラのインスタンスを初期化する。メッセージ ログの記録先となる
* nonCatalogLogger を作成する
*/
public void init(HandlerInfo hi) {
log = new NonCatalogLogger("WebService-LogHandler");
handlerInfo = hi;
}
/**
* Web サービスを実装する Java クラスにメッセージが送信される前に、SOAP
* リクエスト メッセージがログ ファイルに記録されることを指定する
*/
public boolean handleRequest(MessageContext context) {
SOAPMessageContext messageContext = (SOAPMessageContext) context;
System.out.println("** Request: "+messageContext.getMessage().toString());
log.info(messageContext.getMessage().toString());
return true;
}
/**
* Web サービスを呼び出したクライアント アプリケーションにメッセージが送り
* 返される前に、SOAP 応答メッセージがログ ファイルに記録されることを
* 指定する
*/
public boolean handleResponse(MessageContext context) {
SOAPMessageContext messageContext = (SOAPMessageContext) context;
System.out.println("** Response: "+messageContext.getMessage().toString());
log.info(messageContext.getMessage().toString());
return true;
}
/**
* SOAP エラーが Handler インスタンスによって送出された場合、メッセージが
* ログ ファイルに記録されることを指定する
*/
public boolean handleFault(MessageContext context) {
SOAPMessageContext messageContext = (SOAPMessageContext) context;
System.out.println("** Fault: "+messageContext.getMessage().toString());
log.info(messageContext.getMessage().toString());
return true;
}
public QName[] getHeaders() {
return handlerInfo.getHeaders();
}
}
Handler.init()
メソッドは、Handler
オブジェクトのインスタンスを作成し、そのインスタンスが自動的に初期化されるようにするために呼び出されます。そのシグネチャは次のとおりです。
public void init(HandlerInfo config) throws JAXRPCException {}
HandlerInfo
オブジェクトには、SOAP メッセージ ハンドラ情報、特に初期化パラメータが格納されています。HandlerInfo.getHandlerConfig()
メソッドを使用してパラメータを取得すると、このメソッドは、名前と値のペアの入った java.util.Map
オブジェクトを返します。
初期化パラメータを処理する必要がある場合、または、他の初期化タスクを実行する必要がある場合は、init()
メソッドを実装します。
初期化パラメータの使用例としては、デバッグのオン、オフ、メッセージやエラーを書き込むためのログ ファイルの名前の指定などがあります。
Handler.destroy()
メソッドは、Handler
オブジェクトのインスタンスを破棄するために呼び出されます。そのシグネチャは次のとおりです。
public void destroy() throws JAXRPCException {}
destroy()
メソッドを実装すると、ハンドラのライフサイクルを通じて取得されたあらゆるリソースを解放できます。
Handler.getHeaders()
メソッドは、この Handler
インスタンスで処理できるヘッダ ブロックを取得します。そのシグネチャは次のとおりです。
public QName[] getHeaders() {}
Handler.handleRequest()
メソッドは、バックエンド コンポーネントによって処理される前に SOAP のリクエスト メッセージをインターセプトするために呼び出されます。そのシグネチャは次のとおりです。
public boolean handleRequest(MessageContext mc)
throws JAXRPCException,SOAPFaultException {}
このメソッドを実装すると、バックエンド コンポーネントによって処理される前の SOAP メッセージ内のデータの復号化などのタスクが実行できます。
MessageContext
オブジェクトは、SOAP メッセージ ハンドラによって処理されたメッセージのコンテキストを抽出します。MessageContext
プロパティにより、ハンドラ チェーン内のハンドラは処理ステートを共有できます。
MessageContext
の SOAPMessageContext
サブインタフェースを使用すると、SOAP のリクエスト メッセージの内容を取得または更新することができます。SOAP のリクエスト メッセージそのものは、javax.xml.soap.SOAPMessage
オブジェクトに格納されます。このオブジェクトの詳細については、「SAAJ を使用した SOAP リクエスト メッセージおよび応答メッセージの直接操作」を参照してください。
SOAPMessageContext
クラスは、SOAP リクエストを処理する次の 2 つのメソッドを定義します。
SOAPMessageContext.getMessage()
: SOAP のリクエスト メッセージの入った javax.xml.soap.SOAPMessage
オブジェクトを返します。 SOAPMessageContext.setMessage(javax.xml.soap.SOAPMessage)
: SOAP のリクエスト メッセージを変更後、それを更新します。SOAP リクエストのすべての処理をコーディングしたら、次のいずれかを実行します。
true
を返すことにより、ハンドラ リクエスト チェーン内の次のハンドラを呼び出す。 リクエスト チェーンの次のハンドラは、@HandlerChain
アノテーションによって指定されたコンフィグレーション ファイル内の <handler-chain>
要素の次の <handler>
下位要素か、@SOAPMessageHandlers
アノテーションによって指定された配列内の次の @SOAPMessageHandler
のいずれかとして指定されます。チェーン内のすべてのハンドラが実行されたら、Web サービスのコンフィグレーションによって、メソッドは、バックエンド コンポーネントの呼び出し、最終的な SOAP のリクエスト メッセージの送信、または最後のハンドラの handleResponse()
メソッドの呼び出しを行います。
false
を返すことにより、ハンドラ リクエスト チェーンの処理をブロックする。 ハンドラ リクエスト チェーンの処理をブロックすると、Web サービスのこの呼び出しについては、バックエンド コンポーネントは実行されなくなります。Web サービスの一部の呼び出しの結果をキャッシュしてあり、そのリストに現在の呼び出しも含まれている場合は、この操作が便利な場合があります。
ハンドラ リクエスト チェーンの処理を中断されますが、WebLogic Server が、現在のハンドラから順に、response チェーンを呼び出します。たとえば、ハンドラ チェーンに、handlerA と handlerB という 2 つのハンドラがあると想定します。ここで、handlerA の handleRequest()
メソッドは、handlerB の対応するメソッドの前に呼び出されるものとします。handlerA で処理がブロックされると (したがって handlerB の handleRequest()
メソッドは呼び出されない)、ハンドラ応答チェーンは handlerA で開始され、handlerB の handleRequest()
メソッドも呼び出されません。
javax.xml.rpc.soap.SOAPFaultException
を送出して、SOAP 障害を示す。handleRequest()
メソッドが SOAPFaultException
を送出すると、WebLogic Server は、この例外を検出して、ハンドラ リクエスト チェーンの後続の処理を終了し、このハンドラの handleFault()
メソッドを呼び出します。
JAXRPCException
を送出する。 Handler.handleResponse()
メソッドは、バックエンド コンポーネントによって処理された SOAP の応答メッセージをインターセプトするために呼び出されますが、この Web サービスを呼び出したクライアント アプリケーションに返される前に呼び出されます。そのシグネチャは次のとおりです。
public boolean handleResponse(MessageContext mc) throws JAXRPCException {}
このメソッドを実装すると、クライアント アプリケーションに返される前に SOAP メッセージに含まれているデータを暗号化したり、戻り値に処理を加えたりといったタスクを実行できます。
MessageContext
オブジェクトは、SOAP メッセージ ハンドラによって処理されたメッセージのコンテキストを抽出します。MessageContext
プロパティにより、ハンドラ チェーン内のハンドラは処理ステートを共有できます。
MessageContext
の SOAPMessageContext
サブインタフェースを使用すると、SOAP の応答メッセージの内容を取得または更新することができます。SOAP の応答メッセージそのものは、javax.xml.soap.SOAPMessage
オブジェクトに格納されます。「SAAJ を使用した SOAP リクエスト メッセージおよび応答メッセージの直接操作」を参照してください。
SOAPMessageContext
クラスは、SOAP 応答を処理する次の 2 つのメソッドを定義します。
SOAPMessageContext.getMessage()
: SOAP の応答メッセージの入った javax.xml.soap.SOAPMessage
オブジェクトを返します。 SOAPMessageContext.setMessage(javax.xml.soap.SOAPMessage)
: SOAP の応答メッセージを変更後、それを更新します。SOAP 応答のすべての処理をコーディングしたら、次のいずれかを実行します。
true
を返すことにより、ハンドラ応答チェーン内の次のハンドラを呼び出す。 ハンドラ チェーンの次の応答は、@HandlerChain
アノテーションによって指定されたコンフィグレーション ファイル内の <handler-chain>
要素の前の <handler>
下位要素か、@SOAPMessageHandlers
アノテーションによって指定された配列内の前の @SOAPMessageHandler
のいずれかとして指定されます (ハンドラ チェーン上の応答は、JWS ファイルで指定されたのと逆の順序で実行されることに留意してください。詳細については、「SOAP メッセージ ハンドラおよびハンドラ チェーンの設計」を参照してください)。
ハンドラ チェーン内のすべてのハンドラが実行されたら、メソッドは、この Web サービスを呼び出したクライアント アプリケーションに最終的な SOAP の応答メッセージを返します。
false
を返すことにより、ハンドラ応答チェーンの処理をブロックする。 ハンドラ応答チェーンの処理をブロックすると、応答チェーンにある残りのハンドラが、Web サービスのこの呼び出しについては実行されなくなり、現在の SOAP メッセージがクライアント アプリケーションに返されます。
JAXRPCException
を送出する。 Handler.handleFault()
メソッドは、SOAP メッセージ処理モデルに基づいて SOAP 障害を処理します。そのシグネチャは次のとおりです。
public boolean handleFault(MessageContext mc) throws JAXRPCException {}
このメソッドを実装すると、バックエンド コンポーネントによって生成された障害のほか、handleResponse()
メソッドおよび handleRequest()
メソッドによって生成されたあらゆる SOAP 障害の処理も扱うことができます。
MessageContext
オブジェクトは、SOAP メッセージ ハンドラによって処理されたメッセージのコンテキストを抽出します。MessageContext
プロパティにより、ハンドラ チェーン内のハンドラは処理ステートを共有できます。
MessageContext
の SOAPMessageContext
サブインタフェースを使用すると、SOAP メッセージの内容を取得または更新することができます。SOAP メッセージそのものは、javax.xml.soap.SOAPMessage
オブジェクトに格納されます。「SAAJ を使用した SOAP リクエスト メッセージおよび応答メッセージの直接操作」を参照してください。
SOAPMessageContext
クラスは、SOAP メッセージを処理する次の 2 つのメソッドを定義します。
SOAPMessageContext.getMessage()
: SOAP メッセージの入った javax.xml.soap.SOAPMessage
オブジェクトを返します。 SOAPMessageContext.setMessage(javax.xml.soap.SOAPMessage)
: SOAP のメッセージを変更後、それを更新します。SOAP 障害のすべての処理をコーディングしたら、次のいずれかを実行します。
javax.xml.soap.SOAPMessage
抽象クラスは、SOAP With Attachments API for Java 1.1 (SAAJ) 仕様の構成要素です。このクラスは、SOAP メッセージ ハンドラ作成時に SOAP のリクエスト メッセージおよび応答メッセージを操作するのに使用します。この節では、SOAPMessage
オブジェクトの基本構造と SOAP メッセージの表示および更新に役立つメソッドのいくつかについて説明します。
SOAPMessage
オブジェクトは、SOAPPart
オブジェクト (SOAP XML ドキュメントそのものが入っている)、または同オブジェクトと添付ファイルで構成されています。
SOAPMessage
クラスの詳細な説明については、SAAJ に関する Javadoc を参照してください。SAAJ の詳細については、http://java.sun.com/xml/saaj/index.html を参照してください。
SOAPPart
オブジェクトには、SOAPEnvelope
オブジェクトに格納された XML SOAP ドキュメントが入っています。このオブジェクトは、実際の SOAP のヘッダと本文を取得するのに使用します。
次の Java コードのサンプルは、Handler
クラスによって提供された MessageContext
オブジェクトから SOAP メッセージを取り出して、その各部を参照する方法を示しています。
SOAPMessage soapMessage = messageContext.getMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
SOAPBody soapBody = soapEnvelope.getBody();
SOAPHeader soapHeader = soapEnvelope.getHeader();
javax.xml.soap.AttachmentPart
オブジェクトには、SOAP メッセージに対するオプションの添付ファイルが入っています。添付ファイルは、SOAP メッセージの残りの部分とは異なり、XML フォーマットの必須部分ではないので、その形式は、単純なテキストからイメージ ファイルまで、さまざまです。
警告 : SOAP メッセージ ハンドラから直接に添付ファイル java.awt.Image
にアクセスする場合は、「SOAP メッセージ ハンドラでの画像添付ファイルの操作」で重要情報を参照してください。
添付ファイルを操作するには、SOAPMessage
クラスの以下のメソッドを使用します。
countAttachments()
: この SOAP メッセージに含まれている添付ファイルの数を返します。getAttachments()
: すべての添付ファイルを取り出し、(AttachmentPart
オブジェクトとして) Iterator
オブジェクトに格納します。createAttachmentPart()
: 他のタイプの Object
から AttachmentPart
オブジェクトを作成します。addAttachmentPart()
: 作成された AttachmentPart
オブジェクトを SOAPMessage
に追加します。この節では、添付ファイル java.awt.Image
にアクセスする SOAP メッセージ ハンドラを作成すること、および clientgen
Ant タスクによって生成されたクライアント JAX-RPC スタブを使用するクライアント アプリケーションから Image
が送信されていることを前提としています。
clientgen
Ant タスクによって生成されたクライアント コードでは、添付ファイル java.awt.Image
は image/gif
ではなく text/xml
の MIME タイプで、呼び出される WebLogic Web サービスに送信され、Image は画像を表す整数のストリームにシリアライズされます。特に、このクライアント コードは次の形式で Image
をシリアライズします。
つまり、受信した Image 添付ファイルを操作する SOAP メッセージ ハンドラでは、このデータ ストリームをデシリアライズして元の Image を作成し直す必要があるということです。
Web サービスのハンドラ チェーンをコンフィグレーションするために JWS ファイルで使用できる標準的なアノテーションは、@javax.jws.HandlerChain
および @javax.jws.soap.SOAPMessageHandlers
の 2 つです。
@javax.jws.HandlerChain
アノテーション (この章では簡単にするため @HandlerChain
とも言う) を使用する場合は、file
属性を使用して、Web サービスと関連付けるハンドラ チェーンのコンフィグレーションが含まれた外部ファイルを指定します。コンフィグレーションには、チェーン内のハンドラのリスト、ハンドラが実行される順序、初期化パラメータなどが含まれます。
以下の場合は、@SOAPMessageHandlers
アノテーションではなく @HandlerChain
アノテーションを JWS ファイルで使用します。
次の JWS ファイルでは、@HandlerChain
アノテーションの使用例を示します。関連の Java コードは太字で示しています。
package examples.webservices.soap_handlers.global_handler;
import java.io.Serializable;
import javax.jws.HandlerChain;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;
import weblogic.jws.WLHttpTransport;
@WebService(serviceName="HandlerChainService",
name="HandlerChainPortType")
// HandlerConfig.xml ファイルでコンフィグレーションされる「SimpleChain」という
// 名前のハンドラ チェーンが、Web サービスのオペレーションが呼び出されるたびに
// 発動することを指定する、標準的な JWS アノテーション
@HandlerChain(file="HandlerConfig.xml", name="SimpleChain")
@SOAPBinding(style=SOAPBinding.Style.DOCUMENT,
use=SOAPBinding.Use.LITERAL,
parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
@WLHttpTransport(contextPath="HandlerChain", serviceUri="HandlerChain",
portName="HandlerChainServicePort")
/**
* この JWS ファイルは、1 つのオペレーション sayHello を含む簡単な
* Java クラス実装の WebLogic Web サービスの基本となる。この Web サービスにはまた、
* @HandlerChain アノテーションで指定されているように、ハンドラ チェーンが
* 関連付けられている
* <p>
* @author Copyright (c) 2005 by BEA Systems, Inc. All Rights Reserved.
*/
public class HandlerChainImpl {
public String sayHello(String input) {
weblogic.utils.Debug.say( "in backend component. input:" +input );
return "'" + input + "' to you too!";
}
}
@HandlerChain
アノテーションを使用する前に、前述の例に示すように、それを JWS ファイルにインポートする必要があります。
@HandlerChain
アノテーションの file
属性を使用し、ハンドラ チェーンのコンフィグレーション情報を含む外部ファイルの名前を指定します。この属性の値は URL です。これは相対でも絶対でもかまいません。相対 URL は、ファイルをコンパイルするために jwsc
Ant タスクを実行した時点での JWS ファイルの場所を基準とします。
Web サービスと関連付けるコンフィグレーション ファイル内のハンドラ チェーンの名前を指定するには、name
属性を使用します。この属性の値は、コンフィグレーション ファイル内の <handler-chain>
要素の name
属性に対応します。
警告 : 1 つの JWS ファイル内に複数の @HandlerChain
アノテーションを指定すると、エラーになります。また、@HandlerChain
アノテーションを @SOAPMessageHandlers
アノテーションと一緒に使用しても、エラーになります。
外部コンフィグレーション ファイルの作成の詳細については、「ハンドラ チェーン コンフィグレーション ファイルの作成」を参照してください。
この節で説明した標準的な JWS アノテーションの詳細については、「Web Services Metadata for the Java Platform specification」を参照してください。
@javax.jws.soap.SOAPMessageHandlers
(この節では簡単にするため @SOAPMessageHandlers
とも言う) アノテーションを使用する場合、JWS ファイル自体の中で、Web サービスのオペレーションの前と後に実行する SOAP メッセージ ハンドラの配列を指定します (@SOAPMessageHandler
アノテーションで指定)。 @SOAPMessageHandler
アノテーションには、ハンドラのクラス名、初期化パラメータ、ハンドラで処理される SOAP ヘッダのリストなどを指定する属性が含まれます。JWS ファイル自体の内部でハンドラのリストを指定するので、ハンドラ チェーンのコンフィグレーションは、Web サービス内に埋め込まれます。
以下の場合に、@SOAPMessageHandlers
アノテーションを使用します。
次の JWS ファイルでは、@SOAPMessageHandlers
アノテーションの簡単な使用例を示します。関連の Java コードは太字で示しています。
package examples.webservices.soap_handlers.simple;
import java.io.Serializable;
import javax.jws.soap.SOAPMessageHandlers;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPMessageHandler;
import javax.jws.WebService;
import javax.jws.WebMethod;
import weblogic.jws.WLHttpTransport;
@WebService(name="SimpleChainPortType",
serviceName="SimpleChainService")
// Web サービスのすべてのオペレーションの呼び出しの前と後に実行される
// SOAP メッセージ ハンドラのリストを指定する標準的な JWS
// アノテーション
@SOAPMessageHandlers ( {
@SOAPMessageHandler (
className="examples.webservices.soap_handlers.simple.ServerHandler1"),
@SOAPMessageHandler (
className="examples.webservices.soap_handlers.simple.ServerHandler2")
} )
@SOAPBinding(style=SOAPBinding.Style.DOCUMENT,
use=SOAPBinding.Use.LITERAL,
parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
@WLHttpTransport(contextPath="SimpleChain", serviceUri="SimpleChain",
portName="SimpleChainServicePort")
/**
* この JWS ファイルは、1 つのオペレーション sayHello を含む簡単な
* Java クラス実装の WebLogic Web サービスの基本となる。この Web サービスにはまた、
* @SOAPMessageHandler/s アノテーションで指定されているように、ハンドラ チェーンが
* 関連付けられている
* <p>
* @author Copyright (c) 2005 by BEA Systems, Inc. All Rights Reserved.
*/
public class SimpleChainImpl {
// デフォルトでは、すべてのパブリック メソッドがオペレーションとして公開される
public String sayHello(String input) {
weblogic.utils.Debug.say( "in backend component. input:" +input );
return "'" + input + "' to you too!";
}
}
@SOAPMessageHandlers
アノテーションおよび @SOAPMessageHandler
アノテーションを使用する前に、前述の例に示すように、それらを JWS ファイルにインポートする必要があります。これらのアノテーションは、javax.jws.soap
パッケージに入っています。
@SOAPMessageHandlers
配列で (@SOAPMessageHandler
アノテーションを使用して) ハンドラをリストした順序により、ハンドラの実行の順序 (オペレーション前なら順序どおりに、オペレーション後なら逆順で) が指定されます。前述のサンプルでは、ハンドラ チェーンにおいて 2 つのハンドラをコンフィグレーションしています。これらのハンドラのクラス名は、examples.webservices.soap_handlers.simple.ServerHandler1
と examples.webservices.soap_handlers.simple.ServerHandler2
です。
@SOAPMessageHandler
の initParams
属性を使用すると、特定のハンドラにおいて予期されている初期化パラメータの配列を指定できます。@InitParam
標準 JWS アノテーションを使用し、次の例のように、名前と値のペアを指定します。
@SOAPMessageHandler(
className = "examples.webservices.soap_handlers.simple.ServerHandler1",
initParams = { @InitParam(name="logCategory", value="MyService")}
)
また、@SOAPMessageHandler
アノテーションには、ハンドラによって実装される SOAP ロールをリストするための roles
属性、およびハンドラによって処理される SOAP ヘッダをリストするための headers
属性も含まれています。
警告 : @SOAPMessageHandlers
アノテーションを @HandlerChain
アノテーションと一緒に使用すると、エラーになります。
この節で説明した標準的な JWS アノテーションの詳細については、「Web Services Metadata for the Java Platform specification」を参照してください。
JWS ファイルで @HandlerChain
アノテーションを使用して、ハンドラ チェーンを Web サービスと関連付けることにした場合は、ハンドラ チェーン内のハンドラのリスト、それらの実行順、初期化パラメータなどを指定する外部コンフィグレーション ファイルを作成する必要があります。
このファイルは、JWS ファイルの外部にあるため、この単一のコンフィグレーション ファイルを複数の Web サービスで使用するようにコンフィグレーションし、エンタープライズ内のすべての Web サービスに関してハンドラ コンフィグレーション ファイルを標準化できます。加えて、すべての Web サービスを再コンパイルすることなく、ハンドラ チェーンのコンフィグレーションを変更できます。なお、非 SOAP の転送を使用するハンドラ チェーンにハンドラを入れた場合、@SOAPMessageHandler
アノテーションではなく @HandlerChain
アノテーションを使用することが必要となります。
コンフィグレーション ファイルは、次の簡単なサンプルに示すように、XML を使用して 1 つまたは複数のハンドラ チェーンをリストします。
<jwshc:handler-config xmlns:jwshc="http://www.bea.com/xml/ns/jws"
xmlns:soap1="http://HandlerInfo.org/Server1"
xmlns:soap2="http://HandlerInfo.org/Server2"
xmlns="http://java.sun.com/xml/ns/j2ee" >
<jwshc:handler-chain>
<jwshc:handler-chain-name>SimpleChain</jwshc:handler-chain-name>
<jwshc:handler>
<handler-name>handler1</handler-name>
<handler-class>examples.webservices.soap_handlers.global_handler.ServerHandler1</handler-class>
</jwshc:handler>
<jwshc:handler>
<handler-name>handler2</handler-name>
<handler-class>examples.webservices.soap_handlers.global_handler.ServerHandler2</handler-class>
</jwshc:handler>
</jwshc:handler-chain>
</jwshc:handler-config>
この例では、SimpleChain
というハンドラ チェーンに、handler1
および handler2
という 2 つのハンドラが入っています。これらは <handler-class>
要素で指定されるクラス名で実装されます。2 つのハンドラは、関連の Web サービス オペレーションの前には昇順で実行され、オペレーション実行後には逆順で実行されます。
ハンドラ初期化パラメータ、ハンドラによって実装される SOAP ロール、およびハンドラによって処理される SOAP ヘッダを指定するには、それぞれ <handler>
要素の <init-param>
、<soap-role>
、および <soap-header>
子要素を使用します。
外部コンフィグレーション ファイルを定義する XML スキーマ、その作成に関する詳細、およびさらなるサンプルについては、「Web Services Metadata for the Java Platform specification」を参照してください。
この節では、Web サービスをコンパイルおよびビルドする作業用の build.xml
Ant ファイルがあり、ハンドラ チェーンが含まれるように、そのビルド ファイルを更新すると仮定しています。この build.xml
ファイルの作成については、「WebLogic Web サービスの反復的な開発」を参照してください。
メッセージ ハンドラのコンパイルとビルドが含まれるように開発環境を更新するには、以下のガイドラインに従います。
@HandlerChain
または @SOAPMessageHandlers
アノテーションで JWS ファイルを更新後、jwsc
Ant タスクを再実行して、JWS ファイルを再コンパイルし、新しい Web サービスを生成する必要がある。これは、JWS ファイル内のアノテーションに変更を加えた場合は常に当てはまります。JWS ファイルで @HandlerChain
アノテーションを使用し、jwsc
Ant タスクを再実行して Web サービスを再生成し、その後、外部コンフィグレーション ファイルだけを変更した場合は、2 度目の変更を有効にするために jwsc
を再実行する必要はありません。
jwsc
Ant タスクは SOAP メッセージ ハンドラ Java ファイルをハンドラ クラスにコンパイル (およびその後それらを生成されたアプリケーションにパッケージ化) する。@HandlerChain
または @SOAPMessageHandler(s)
アノテーションにおいて参照される。sourcepath
属性で指定されたディレクトリ内に置かれる。ハンドラ クラスを jwsc
で自動的にコンパイルするのではなく、ユーザ側でコンパイルする場合は、jwsc
Ant タスクを実行する前に、コンパイルされたクラスが CLASSPATH 内にあることを確認してください。
![]() ![]() |
![]() |
![]() |