レベル: 上級 Sonny Fulkerson, Senior Technical Staff Member, IBM Corporation Hidayatullah Shaikh (hshaikh@us.ibm.com), Senior Software Engineer, IBM, Software Group
2004年 3月 09日 Web サービスが配備されると、通常はアドレスが公開され、情報がディレクトリーにバインドされて、クライアントからアクセスできるようになります。一般に、Web サービスのライフサイクルはその配備状態の影響を受けます。ただし、サービスの実装自体は、クライアントに代わって、または特定のビジネス・コンテキスト内で、動的な状態を保持することができます。Web Services Resource Framework では、Web サービスを使用して状態にアクセスするためのモデルが提案されています。このモデルは WS-Addressing プロトコルに基づいて構築されています。この記事では、Web Services Resource Framework で提案されている技法を使用して IBM® WebSphere® Studio Application Developer V5.1.1 で Web サービス資源にアクセスする方法について説明します。
Web サービスは一般にステートレスであると見なされます。確かに、Web サービスへのアクセスは HTTP のようなステートレスで信頼性の低いプロトコルを介して行われることが多いのは事実です。ただし実際には、これらの Web サービスが個別のサービス・リクエスターに代わって、あるいは特定のビジネス・コンテキスト内で、複数の対話に渡って状態や資源を保持するケースはよくあります。例としてよく挙げられるのはショッピング・カート・アプリケーションです。このアプリケーションでは、複数の独立した対話間で、サーバー・アプリケーションが個別のリクエスターに代わってカートの内容を保持することができます。
サーバー・アプリケーションが複数のクライアントからの複数の要求にわたって状態を保持できるようにするには、対話ごとに更新される状態データを識別する方法が必要です。要求を相関させる方法として最も一般的なのは、アプリケーション設計に明示的に組み込む方法です。ショッピング・カートの例で言えば、対話ごとにショッピング・カートの識別子が入力として要求されるような設計が考えられます。こうすることで、商品の追加や削除をどのカートから行えばいいのかをサーバー・アプリケーションが識別できるようになります。
アプリケーション・インターフェースに相関データを置くとクライアント・アプリケーションの負担を招く、と考える設計者もいます。このような考えの設計者は、クライアント・アプリケーションがコードを明示的に組み込む必要のない、暗黙的な相関またはセッションを作成する技法を追及してきました。一般に、これまで提案されてきたアプローチでは、HTTP での cookie のように基盤となる通信プロトコルの機能を使用したり、Web サービス・クライアントのランタイムにこの機能がサポートされるよう明示的に要求したりすることにより、サーバー・アプリケーションにかかわっていました。
ホワイトペーパー「Modeling stateful resource with Web services」(『参考文献』のリンク参照) では、このタスクを実現するためのImplied Resource パターンが提案されています。このパターンでは、サービス・プロバイダーが WS-Addressing プロトコル (『参考文献』参照) の拡張機能を利用して、クライアントの負荷を軽減することが可能です。特定の転送プロトコルに制限されることも、Web サービス・クライアントのランタイムに独自のサポートが要求されることもありません。
この記事では、上記のアプローチの利点については触れていません。その代わり、ステートフル Web サービスへのこれらのアプローチの実装について、私たちの実際の経験を盛り込みました。これらのサービスは、IBM WebSphere Studio Application Developer V5.1.1 を使用して、IBM® WebSphere® Application Server V5.1 上に配備されるものです。既存の J2EE ベスト・プラクティスをサービスの実装に利用すれば、複数のインターフェース・スタイルを簡単にサポートできるほか、手持ちの豊富なツール群やランタイム・サポート機能も活用することができます。
ここでは、サンプルとして、簡単な計算機アプリケーションを使用します。まず、J2EE Session Bean Entity Facade パターンを使用して、この計算機を RMI/IIOP クライアントが使用できるように実装します。次に、このアプリケーションを WSDL インターフェースを介して簡単に Web サービス・クライアントに公開できることを示します。最後に、Implied Resource パターンを使ってこの計算機サービスを公開する際の必要手順と、Web Services Resource Framework で提案されているアプローチを使用して計算機サービスのクライアントを構築する方法について説明します。これらのパターンを利用するアプリケーションの開発に役立つと思われる場合は、将来的なサポートについても取り上げます。この記事のコード・ダウンロード用パッケージには、サービス実装とクライアント・コードが両方収録された EAR が含まれています。
この記事を読むと、ステートフルな資源を実装し、アプリケーション・サーバー内の Web サービス・インターフェースを介してその資源にアクセスする場合の中核的な問題とタスクについて、詳しく知ることができます。また、WS-Addressing などの新しい Web サービス標準に対する正式なランタイム・サポートに先立ち、どの部分でアプリケーションが拡張されるかに関する知識を得ることもできます。この情報を提供する目的は、選択したインターフェース設計によって生じる可能性のある、実装コストと移行に関する潜在的な問題を把握できるようにすることです。
対象読者
この記事は、J2EE、Web サービス、およびアプリケーション・サーバーに関する基本的な知識のある方を対象にしています。このテクノロジーに関する理解を深めたい場合は、この記事の『参考文献』に入門用資料が用意されているのでご利用ください。IBM developerWorks で入手できる資料を参照することもおすすめします。
サンプル・コードの内容と要件
この記事で引用されるサンプルは、WebSphere Studio Application Developer Version V5.1.1 GM 版で作成されたものです。これらのサンプルは、WebSphere Application Server V5.1 に組み込まれたテスト環境において単体でテストされました。
ファイル ws-statefulwscode.zip には、この記事に収録されたコード・サンプルが含まれています。このファイルは、この記事の最上部または最下部にある「Code」アイコンをクリックするとダウンロードすることができます。このファイルには、次のファイルが含まれます。
WASv5WSAExtensions.jar
| SOAP メッセージの WS-Addressing メッセージ情報ヘッダーの作成時やアクセス時に WebSphere Application Server V5.1 によって必要とされる、ユーティリティー・クラスが含まれた JAR ファイル。WS-Addressing のエンドポイント・リファレンスを操作するためのヘルパー・クラスも含まれています。これらのクラスは、WebSphere Studio アプリケーションでの用途に応じて構成することができます。 |
WASvsWSAExtensions-javadoc.zip
| ユーティリティー・クラスの javadoc。 |
CalculatorService.ear
| ステートフルな計算機サービス (サンプル)。計算機サービスを簡単に呼び出すことのできる Web アプリケーションが提供されます。 |
EJB クライアント用の計算機サービスの実装
リスト 1 に、RMI/IIOP クライアントが利用できる計算機サービスのインターフェースを示します。
リスト 1 . Calculator service interface for remote RMI/IIOP clients
public interface CalculatorService extends Remote {
public float add(float value1, float value2) throws java.rmi.RemoteException;
public float sub(float value1, float value2) throws java.rmi.RemoteException;
}
|
この計算機サービスのインターフェースは、オペレーションの実行に必要な情報をすべてリクエスターが入力しなければならないように設計されています。結果はオペレーションの出力として返されます。一般に、このようなタイプのサービスは「リクエスターとの対話に関してステートレスである」と見なされます。このようなインターフェース設計では、各要求を独立した対話として処理することができるので、サービス実装者の手間が省けます。リスト 2 に、この実装のシンプルさがよくわかるコード断片を示します。
リスト 2 . Implementation of the calculator service add() operation
public float add(float value1, float value2)
{
// Add the two input values and return result. Note, that we do not need to
// reference any requestor state to perform the operation
return value1 + value2;
}
|
このサービスの開発における次の手順は、各ユーザーに特定の計算機インスタンスを割り当てることです。これにより、各リクエスターはこの計算機で加算や減算を行ったり、現在の計算値を照会したりすることができます。一般に、特定のリクエスターに代わって情報を保持するサービスは「そのリクエスターとの対話に関してステートフルである」と見なされます。
クライアントに代わって計算機の合計値を保持する場合にサービス実装者が利用できる方法は、数多くあります。対象となる計算機の状態を把握する手段として、各要求で利用できる既存のコンテキストをサービス実装で使用することもできます。例えば、実装者が各要求のセキュリティー・コンテキストからリクエスターのユーザー ID を取得し、それを使用してターゲットの計算機の合計値を識別することも可能です。
セキュリティー・コンテキストでリクエスターを識別し、リクエスターと計算機の状態の間で一対一の対応付けをする方法は、機能的には問題はないものの、優れたアプリケーション設計とは言えません。特定の計算機の合計値にアクセスするために要求を対応付ける手段としては、相関関係を計算機サービス・インターフェースの正式な部分に組み込むという方法もあります。リスト 3 に、書き換えられたインターフェースを示します。
リスト 3 . Calculator service interface with explicit state identifier
public interface CalculatorService extends Remote {
public String getCalculator(String AcctName) throws java.rmi.RemoteException;
public float add(String calcID, float value) throws java.rmi.RemoteException;
public float sub(String calcID, float value) throws java.rmi.RemoteException;
public float getTotal(String calcID) throws java.rmi.RemoteException;
}
|
更新されたインターフェースには、アカウント名を入力として使用する getCalculator() メソッドが含まれています。例えば、リクエスターがいずれかの帯域外管理プロセスからアカウント名を入手済みであるとします。getCalculator() メソッドは計算機インスタンスを作成するファクトリーとして機能し、リクエスターに calcID を返します。リクエスターが自分の現在の計算機で続けて加算や減算を行ったり、合計値を照会したりする場合は、要求パラメーターに自分の calcID を指定し、適切な計算機サービス・オペレーションを呼び出すだけで済みます。calcID は計算機サービスにアクセスするプログラムからは不透明です。
CalculatorService.ear には、J2EE Session Bean Entity Facade パターンを使用して更新された CalculatorService インターフェースの実装が含まれます。このパターンでは、計算機の基盤となる状態がサービス実装でどのように保持されるかについてリクエスターが詳細を知る必要はありませんが、計算機サービスへのアクセスに関するビジネス・ルールを追加制定するための手段は提供されます。そのため、このパターンはベスト・プラクティスであると考えられます。例えばプロバイダーは、リクエスター用の計算機を作成する前に、そのリクエスターがサービスへのアクセス料金を支払っている組織に属しているかどうかを確認するロジックを追加できます。リスト 4 に、計算機サービスの Session Bean コントローラー内に存在する可能性のあるロジックを示します。
リスト 4 . The session bean acts as a controller for the calculator service
public String getCalculator(String AccountName)
{
// Determine if requestor has business entitlements to create a calculator
// instance. This function will check if payments have been made and insure
// that the department has not used up all of its calculators
// Create a calculator total, set it to zero. Build a calculator identifier to
// be returned to the requestor
If (acctAllowedToCreateMoreCalcs(AccountName)) == true) {
calcID = this.generateCalcID();
home.create(calcID()); // Call the EJB Entity Bean home to create a
// Calculator State object with the calcid
}
:::
:::
return calcID;
}
|
このサンプル・アプリケーションは、基盤となる永続性メカニズムとしてリレーショナル・データベースを利用する CMP エンティティーによって、計算機の状態を保持します。この方法を選んだのは、永続性に対するランタイム・サポートとツーリング・サポートが最も多く提供され、かつアプリケーションの要件を満たしているからです。パフォーマンスを強化する手段として、EJB ローカル・インターフェースを利用することができます。サービス実装者が計算機の状態を保持する方法は、これ以外にもあります。例えば、データベースやメモリ内ハッシュ・テーブルを利用する方法や、状態の属性を構成する 1 つ以上のレガシー・システムにアクセスする方法もあります。サービス・プロバイダーがどのような手段で状態を指定して保持するかは、アプリケーション設計からは切り離せない部分であり、その方法はサービスの要件と、サービスを実行する環境の制約によって左右されます。
ここでは、割り当てられた計算機を、リクエスターが明示的に返したり破棄したりすることは要求されません。一定時間使用されない場合、計算機は失効するものとします。このことは、計算機のリクエスターがアカウントを開いたときに通知されます。状態のタイムアウトを管理する技法はこの記事では取り上げません。その代わり、基盤となるデータベースを定期的に調べてクリーンアップを実行するバックグラウンド・リーパーがあるものとします。使用状況に関する測定基準 (作成時刻、最終アクセス時刻など) は、計算機の状態を保存する、基盤となるデータベースに含めます。現時点では、これらの属性を計算機サービスを通じて公開することはしません。
計算機サービスを Web サービスとして公開
CalculatorService.ear には、更新された計算機インターフェースを Web サービスとして公開するコードも含まれています。このコードは、SOAP over HTTP を使用して呼び出すことができます。J2EE 標準では、Web サービスは Java クラス (Web コンテナー内) またはステートレス Session Bean として実装できると規定されています。WSAD の Web Services ウィザード・サポートの使用により、この計算機サービスのステートレス Session EJB コンポーネントを Web サービスとして公開するために必要な成果物を、簡単に生成することができました。このサポートには、サービスを呼び出すための WSDL およびサンプル用クライアント・コードの生成が含まれています。また、新しい Web サービス・エクスプローラーを使用して、作成したサービスを単体テストすることもできました。このエクスプローラーでは、サービス定義に基づいてサービスを呼び出すための、Web ベースのインターフェースを生成することができます。
Web サービスは実際にはメッセージ交換を通じて相互運用性に対応していることを思い出してください。この計算機サービス用にメッセージ形式とプロトコルのバインディングを記述する WSDL ドキュメントは定義済みなので、適切なメッセージを生成し、適切なプロトコルで送信できるクライアント・プログラムであれば、いずれもこのサービスを呼び出すことができます。つまり、この計算機サービスはもはや RMI/IIOP クライアントに限定されなくなったのです。リスト 5 に、計算機サービスをターゲットとする有効な SOAP メッセージを示します。
リスト 5. A sample SOAP-over-HTTP message targeted to our calculator service
001 POST /Calculator HTTP/1.1
002 Host: XYZ.com
003 Content-Type: text/xml; charset=utf-8
004 Content-Length: 99999
005 SOAPAction:
006 <?xml version="1.0" encoding="UTF-8"?>
007 <soapenv:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:sec="...">
008 <S:Header>
009 <sec:Security>
<!-- WS-Security signature of Body, To, -->
<!-- Action and From goes here. --> ...
010 </sec:Security>
011 </S:Header>
012 <S:Body>
013 <add xmlns="http://calculator.ibm.com">
014 <CalculatorID>DEPT23CALC</CalculatorID>
015 <value>100</value>
016 </add>
017 </S:Body>
018 </soapenv:Envelope>
|
このメッセージを詳しく見てみましょう。行 6 から 18 は、エンドポイント http://XYZ.com/Calculator に送信される SOAP メッセージを表しています。これは、計算機サービスが含まれている WebSphere Application Server の Web サービス・ランタイムのエンドポイントのアドレスです。アプリケーション・サーバーはメッセージの内容を問い合わせ、必要なコンテキスト・セットアップを実行した後、配置されたサービス実装の構成に基づいて、サービス実装にディスパッチします。この記事の例では、ステートレス Session Bean の add() メソッドにディスパッチされます。
行 8 から 11 は、SOAP ヘッダー形式での制御情報を表しています。新しいタイプの制御情報が続々と定義され、Web サービス・ランタイムと仲介プログラムでサポートされるようになってきています。WebSphere Application Server V5.0.2 には、WS-Security ヘッダーで伝送されるセキュリティー・トークンを解釈するためのサポートが含まれています。具体的には、アプリケーション・サーバーは構成された認証サービスを使ってトークンを検証することができます。トークンが有効であれば、アプリケーション・サーバーはそれをセキュリティー・プリンシパルにマップすることができます。コンポーネントをディスパッチする前に、サービス実装で定義されているセキュリティー制約が満たされていることを確認できるように、プリンシパルは J2EE コンテキストとして構築されています。最終的には、この Web サービスを表しているステートレス Session Bean は、RMI/IIOP クライアントから呼び出されたものか、Web サービス・リクエスターからのメッセージの結果呼び出されたものかを問わず、同じ API を通じてセキュリティー・コンテキストを取得できるようになっています。アプリケーション・サーバーは、理解できない SOAP ヘッダーを無視します。
行 12 から 17 は、SOAP ボディを表します。この情報は、計算機サービス実装にディスパッチするために使用されます。特筆すべき点は、既存の CalculatorService Java インターフェースのすべてのパラメーター型が有効な XML および WSDL 構成体にクリーンにマップされるために、実装が含まれている既存のステートレス Session Bean を変更しなくても Web サービスをボトムアップ式に生成できたことです。ここでは、アプリケーション・サーバーが解釈でき、既存インターフェースにディスパッチできるようなメッセージ・パートを定義しただけで済みました。これは最もうまく行った場合のシナリオで、開発と更新が双方向で可能な WSDL ドキュメントと Java 実装が得られます。
CalculatorTestExecute.jsp には、計算機サービスを Web サービスとして呼び出すためのサンプル用クライアント・コードが含まれています。このコードは、サービスへのアクセスに標準の J2EE プログラミング・モデルを利用しています。リスト 6 に、計算機サービスを呼び出すためのクライアント・コードを示します。
リスト 6. J2EE client code for invoking the calculator service
// Lookup Calculator Service Interface using standard JNDI
com.ibm.calculator.CalculatorService calculatorSI =
(com.ibm.calculator.CalculatorService)
ic.lookup("java:comp/env/service/CalculatorService");
// Get an invokable Stub for service using standard J2EE programming model
com.ibm.calculator.Calculator calculator =
(com.ibm.calculator.Calculator)
calculatorSI.getPort(com.ibm.calculator.Calculator.class);
// Obtain a calculator supplying my account name as input
String calcID = calculator.getCalculator(acctName);
// Invoke the service
calculator.add(calcID, 12);
:::
|
Application Developer の拡張により WS-Addressing メッセージ・ヘッダーを生成
WS-Addressing 標準は、通常は通信伝送ヘッダーに埋め込まれているアドレッシングおよびアクション情報を SOAP エンベロープ内に置くように指定しています。特にこの仕様では、エンドポイント・リファレンスと呼ばれるポータブルなアドレス構成体用のスキーマが定義されています。また、この情報を Web サービス・エンドポイントに送信される SOAP メッセージのメッセージ情報ヘッダーとして表現するための一連のルールも定義されています。このようなサポートによって、通信プロトコルに対する SOAP メッセージの依存性を弱めることができるほか、Web サービスから Web サービスへ参照を渡したり、Web サービスから他のサービスへ参照を渡したりする際の手段も定義されます。記事「Expanding the communications capabilities of Web services with WS-Addressing」 (『参考文献』のリンク参照) には、WS-Addressing の使用例が掲載されています。
リスト 7 に、クライアント・プログラムから送信された、計算機サービスをターゲットとするメッセージを示します。このプログラムでは、WS-Addressing 情報が制御セクションに組み込まれています。このクライアント Web サービス・ランタイムには、WS-Security ヘッダーも組み込まれています。
リスト 7. Sample SOAP/HTTP message for calculator service containing WS-Addressing information
001 POST /Calculator HTTP/1.1
002 Host: XYZ.com
003 Content-Type: text/xml; charset=utf-8
004 Content-Length: 99999
005 SOAPAction:
006 <?xml version="1.0" encoding="UTF-8"?>
007 <soapenv:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:sec="..."
xmlns:wsa="...">
008 <S:Header>
009 <wsa:to>http://XYZ.com/services/Calculator</wsa:to>
010 <sec:Security>
<!-- WS-Security signature of Body, To, -->
<!-- Action and From goes here. --> ...
011 </sec:Security>
012 </S:Header>
013 <S:Body>
014 <add xmlns="http://calculator.ibm.com">
015 <CalculatorID>DEPT23CALC</CalculatorID>
016 <value>100</value>
017 </add>
018 </S:Body>
019 </soapenv:Envelope>
|
行 9 には WS-Addressing 情報が含まれています。Web サービス・ランタイムはさらに拡張され、WS-Addressing で指定されているように、サービス・エンドポイントに送信される SOAP メッセージのヘッダーにメッセージ情報ヘッダーが含まれるようになっています。IBM Emerging Technologies Toolkit (ETTK、『参考文献』のリンク参照) には、WS-Addressing ヘッダーを作成するために Axis を拡張するハンドラーが含まれています。Microsoft Web Service Extensions (WSE) 2.0 ツールキットは、.Net 環境用の同様の機能を備えています。
WASv5WSAExtensions.jar には、アプリケーション・サーバー内で使用するための JAX-RPC クライアント・ハンドラーが含まれています。クライアント・アプリケーションでハンドラーが構成されると、そのハンドラーによって、アプリケーションからの送信メッセージに WS-Addressing メッセージ情報ヘッダーが追加されます。ハンドラーは既存の情報からメッセージ・ヘッダーを作成できるので、このサポートを有効にするためにクライアント・アプリケーション・プログラムに変更を加える必要はありません。
ハンドラーを使用するには、WASv5WSAExtensions.jar を Web サービス・クライアント・アプリケーションのクラスパス上に置かなければなりません。これを行うには、JAR ファイルをワークスペースにインポートし、それが従属した JAR ファイルとして組み込まれるように、Web サービス・クライアントのプロジェクト・プロパティーを更新します。その後、Web サービス・クライアントのデプロイメント記述子にハンドラー定義を追加します。リスト 8 に、計算機サービスの Web サービス配備記述子に加えた更新を示します。WSAD 内のデプロイメント記述子エディターを利用すると、これらの更新を簡単に行うことができます。
リスト 8. Updates to the webservicesclient.xml file of the CalculatorServiceWebClient application
<handler>
<handler-name>com.ibm.samples.wsa.handler.ClientHandler</handler-name>
<handler-class>com.ibm.samples.wsa.handler.ClientHandler</handler-class>
</handler>
|
計算機の状態を Web サービス資源として表現
先に述べた Implied Resource パターンには、ターゲット Web サービスを識別する場合や、サービス実装によって処理内で使用される資源の情報伝送を支援する場合の、WS-Addressing エンドポイント・リファレンス要素の使用方法が記述されています。このアプローチで使用されている WS-Addressing プロトコルは、SOAP ボディのメッセージ内で要素を定義するのではなく、SOAP メッセージのヘッダー・セクションを利用します。具体的には、WS-Addressing のエンドポイント・リファレンスのリファレンス・プロパティー部に、使用する資源 (Web サービスが解釈できる資源) の識別子を含めることが提案されています。
計算機を Web サービス資源として公開するには、まず CalculatorService の WSDL ファイルにある getCalculatorResponse メッセージを変更し、calcID ではなく、WS-Addressing スキーマの定義に従ったエンドポイント・リファレンスが含まれるようにします。同様に、calcID の情報は、計算機 Web サービスのアドレス指定に使用される WS-Addressing エンドポイント・リファレンスにカプセル化されることになるため、add、sub、getTotal の各入力メッセージから calcID 要素を削除します。リスト 9 に、更新済みの WSDL を WSDL2Java ユーティリティーを通じて実行した後に得られるサービス・エンドポイント・インターフェースを示します。
リスト 9. Implied Resource pattern that allows us to remove the data identifier from the functional interface
public interface CalculatorService extends Remote {
public javax.xml.soap.SOAPElement getCalculator(String AcctName)
throws java.rmi.RemoteException;
public float add(float value) throws java.rmi.RemoteException;
public float sub(float value) throws java.rmi.RemoteException;
public float getTotal() throws java.rmi.RemoteException;
}
|
ここでは、WSDL2Java ユーティリティーが、getCalculator() サービス・インターフェース・メソッドからの戻り型を生成するときに、getCalculator 応答メッセージからのエンドポイント・リファレンスのスキーマ型を SOAPElement にマップしています。これは、エンドポイント・リファレンスのスキーマ定義に、拡張性型の anyattribute が含まれていることによって生じます。この可変性により、この型は JAX-RPC 1.1 仕様で指示されている WSDL から Java へのマッピング・ルールから外れます。メッセージ・パートがルールから外れると、Web サービス・ランタイムは、マップされた型ではなく汎用の SOAPElement として、そのルールをアプリケーションに提供します (その逆の場合もあります)。
上の解説に基づき、getCalculator() メソッドの実装者は、エンドポイント・リファレンス用の XML 構成体が含まれた SOAPElement を戻り型として生成する必要があります。WASv5WSAExtensions.jar には、このタスクに利用できるエンドポイント・リファレンスのヘルパー・クラスが含まれています。このエンドポイント・リファレンス・クラスは、エンドポイント・リファレンス (EPR) 用のスキーマの Java マッピングです。このクラスは、SOAPElement から Java EPR インスタンスを初期化するためのサポートと、Java EPR インスタンスを SOAPElement に直列化するためのサポートを提供します。
リスト 10 に、更新された getCalculator() メソッド内のロジックを記述するコード断片を示します。CalculatorService.ear には全ソース・コードが含まれており、計算機を Web サービス資源として公開するために加えられた更新が示されています。
リスト 10. getCalculator() method updated to return a SOAPElement containing an EPR
public javax.xml.soap.SOAPElement getCalculatorEPR(String AccountName) {
EndpointReference epr = null;
SOAPElement eprAsSOAPElement = null;
try {
// If this account has not reached its maximum limit of calculators
if (acctAllowedToCreateMoreCalcs(AccountName) == true) {
CalculatorStateLocalHome home = getCalculatorStateHome();
if (home != null) {
String calcID = generateCalcID(); // Generate an ID to
be assigned to this Calculator
home.create(calcID); // Call EJB home to
create the Calculator State
epr = new EndpointReference();
String address = EPRHelper.getEndpointAddressFromCurrentContext();
epr.setAddress(address);
epr.setReferenceProperty(CALCULATOR_NS,
CALCULATOR_LOCALNAME_CALCID,
calcID);
eprAsSOAPElement = epr.toSOAPElement();
return eprAsSOAPElement;
...
|
現在、getCalculator() ファクトリー・メソッドは、このサービスで作成される計算機がすべて同じサービス・エンドポイントを介してアクセスされることを前提とした、ごくシンプルなアプローチを取っています。メソッドの実装では、提供されたヘルパー・クラスを使用して、エンドポイント・アドレスを確定しています。実際は、このメソッドの実装はさらに推敲することができます。特に、この資源を割り当てるのに最も適したエンドポイント・アドレスを、サービス・レジストリーまたはワークロード・マネージャーで決定するといったことも可能です。EPR の内容を決定する作業は環境に大きく左右されるので、この記事では取り上げません。
リスト 11 に、Implied Resource パターンで計算機サービスにアクセスするためにクライアント・コードに加える必要のある更新を示します。
リスト 11. Client updates needed to access the calculator service using the Implied Resource pattern
com.ibm.samples.calculator.CalculatorService calculatorService = null;
// Initial Context
javax.naming.InitialContext ic = new javax.naming.InitialContext();
// Lookup calculatorFactory SI
// Returns object support javax.xml.rpc.Service
com.ibm.samples.calculator.CalculatorServiceService calculatorServiceSI
= (com.ibm.samples.calculator.CalculatorServiceService) ic.lookup
("java:comp/env/service/CalculatorServiceService");
// Get the calculatorFactory SEI
// Object that supports CalculatorService remote interface
calculatorService = (com.ibm.samples.calculator.CalculatorService)
calculatorServiceSI.getPort(com.ibm.samples.calculator.
CalculatorService.class);
if(calculatorService != null)
{
try
{
javax.xml.soap.SOAPElement SE = calculatorService.getCalculator(acctName);
com.ibm.samples.wsa.wsaddr.EndpointReference epr
= com.ibm.samples.wsa.wsaddr.EndpointReference.fromSOAPElement(SE);
com.ibm.samples.wsa.utils.JAXRPCHelper.setEPR( (javax.xml.rpc.Stub)
calculatorService, epr);
calculatorService.add(addvalue);
}
|
更新された getCalculator() 応答メッセージに対応できるように、クライアント・インターフェースも再生成されています。その結果、Java クライアントは Web サービス・ランタイムから getCalculator() オペレーションの出力として SOAPElement を受け取るようになります。
クライアント・プログラムは、EPR を名前/値のペアとして計算機サービスのスタブに格納します。クライアント・ハンドラー (構成方法についてはこの記事の前半を参照) を使用すると、スタブ内の EPR を調べることができます。EPR が存在する場合、クライアント・ハンドラーはこの情報を取り出して、アウトバウンド・メッセージに WS-Addressing メッセージ情報ヘッダーを作成します。
ここまでのセクションでは、Web サービス資源によって限定された EPR を getCalculator() メソッドで生成し、それをクライアントに返す方法を説明してきました。また、EPR であると判断したものをそのクライアントが受け取る際の方法や、CalculatorService スタブ・インスタンスを取り込む方法についても説明してきました。CalculatorService スタブ・インスタンスを取り込むと、スタブを経由する後続の要求が SOAP メッセージ・ヘッダーとして EPR 情報を組み込めるようになります。リスト 12 に、Web サービス実装として動作するステートレス Session Bean がどのような方法で WS-Addressing リファレンス・プロパティーにアクセスするのかを示します。この WS-Addressing リファレンス・プロパティーは、クライアントから送られたメッセージ・ヘッダー内に存在します。
リスト 12. Sample code for retrieving WS-Addressing information from message context
:::
public float add(float value) {
float _newTotal = 0f;
try {
CalculatorStateLocalHome home = getCalculatorStateHome();
if (home != null) {
String calcID =
EPRHelper.getReferencePropertyFromContext(
CALCULATOR_NS,
CALCULATOR_LOCALNAME_CALCID);
CalculatorStateLocal calculatorState =
home.findByPrimaryKey(calcID); //
if (calculatorState != null) {
_newTotal =
calculatorState.getTotal() + value;
calculatorState.setTotal(_newTotal);
}
}
} catch (FinderException e) {
e.printStackTrace();
} catch (SOAPException e) {
e.printStackTrace();
}
return _newTotal;
}
|
CalculatorService の add() メソッドの実装では、計算機の状態を識別する calcID を入力パラメーターとして取得しなくなっています。calcID の値は、入力メッセージで到着したリファレンス・プロパティー情報から取得されています。特に、ヘッダー情報の EPR 表現は SOAP メッセージ・コンテキストから取得されます。
Get thetools used in this article
If you are a developerWorks subscriber, you have a single user license to use
WebSphere Studio Application Developer
, and other DB2®, Lotus®, Rational®, Tivoli®, and WebSphere products -- including the Eclipse-basedWebSphere Studio IDE -- to develop, test, evaluate, and demonstrate your applications. Ifyou are not a subscriber, you can
subscribetoday
.
結論
この記事では、クライアントとの契約に関してステートフルなサービスとステートレスなサービスの例を紹介しました。具体的には、状態を利用するアプリケーションを実装する際の一般的なベスト・プラクティスおよび設計パターンが存在することを示したほか、ごくわずかの変更でこれらの実装を Web サービス・クライアントに拡張し、クライアントに与えられた新機能を実装に利用できることを紹介しました。
ここで提供したのは、これらのアプリケーションの構築に役立つ最低限のヘルパー・クラスとドキュメンテーションです。私たちは、より高レベルのプログラミング・モデルとランタイム・サポートがこれからも登場し、アプリケーション・プロバイダーを細かい設定から解放してくれるものと期待しています。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| ws-statefulwscode.zip | ws-statefulwscode.zip | 413KB |
FTP |
|---|
参考文献
- Read the other parts of the series "Implement and access stateful Web services using WebSphere Studio:"
- For more on the Implied Resource pattern, see "Modeling stateful resource with Web services," by Ian Foster, Jeffrey Frey, Steve Graham, Steve Tuecke, Karl Czajkowski, Don Ferguson, Frank Leymann, Martin Nally, Tony Storey, William Vambenepe, and Sanjiva Weerawarana (Whitepaper, developerWorks, January 2004)
- For more on the Web Services Resource Framework, see "Web Services Notification and Web Services Resource Framework," a set of specifications at IBM developerWorks.
- WS-Addressing is an XML serialization and standard SOAP binding for representing network-wide pointers to services. You can download the specification from IBM developerWorks.
- For more information on accessing and developing Web services in WebSphere Studio, check out "Support for J2EE Web Services in WebSphere Studio Application Developer V5.1, Part 1: The server environment," by Greg Flurry (developerWorks, October 2003)
- For more on WebSphere Studio and Web services, take a look at the developerWorks
Web services demos with WebSphere Studio.
- For more examples of WS-Addressing in action, read "Expanding the communications capabilities of Web services with WS-Addressing," by John Shewchuk, Steve Millet, Hervey Wilson, and Damon Cole (MSDN, October 2003)
- The IBM Emerging Technologies Toolkit provides handlers to extend Axis to create WS-Addressing headers.
-
JSR 109 establishes that, under J2EE, a Web service may be implemented as a Java class (within the Web container) or as a stateless session bean.
- Visit the Developer Bookstore for a comprehensive listing of technical books, including hundreds of Web services titles.
- Want more? The developerWorks SOA and Web services zone hosts hundreds of informative articles and introductory, intermediate, and advanced tutorials on how to develop Web services applications.
著者について  | |  | Sonny Fulkerson is a Senior Technical Staff Member working in the IBM On Demand Development organization. He is based in Research Triangle Park, North Carolina. |
 | |  | Hidayatullah H. ShaikhはIBM T.J. Watson Research Centerのオンデマンド・アーキテクチャーと開発チームのシニア・ソフトウェア技術者です。関心領域は広く、ビジネス・プロセスのモデル化と統合、サービス指向アーキテクチャー、グリッド・コンピューティング、eコマース、エンタープライズJava、データベース管理システム、それに高可用性クラスターに渡っています。連絡先はhshaikh@us.ibm.comです。 |
記事の評価
|