 | レベル: 中級 Hidayatullah Shaikh (hshaikh@us.ibm.com), Senior Software Engineer, IBM
2004年 6月 08日
Web Services Resource Framework では、Web サービスを使用して状態にアクセスするためのモデルが提案されています。WS-Resource Properties 仕様では、Web サービス・テクノロジーを使用して、ステートフルな資源に関連付けられたデータを照会および変更する方法が定義されています。これにより、WS-Resource に関連付けられたデータにクライアントがアクセスする際に利用できる標準手段が提供されます。この記事では、IBM® WebSphere® Studio Application Developer V5.1 によって WebSphere Application Server 環境で WS-Resource プロパティーを実装する方法について説明します。
WS-Resource Properties 仕様には、サービス・リクエスターが Web サービス・インターフェースを通じて、WS-Resource の状態の型と値を表示および修正するための手段が記述されています。WS-Resource の状態は、XML スキーマを使用した XML 資源プロパティー・ドキュメントとして表現されます。WS-Resource Properties 仕様では、資源のプロパティーの定義を Web サービス・インターフェースの一部として宣言するための手段が標準化されています。また、リクエスターが暗黙的資源インスタンスのプロパティー値を照会または更新できるようにするための、メッセージ交換の標準セットも定義されています。
この記事では、シンプルな計算機サービスの例を使用して、IBM WebSphere Application Server 環境で WS-Resource プロパティーを指定したり、アクセスしたりする方法を説明します。
対象読者
この記事は、J2EE テクノロジー、Web サービス、および WebSphere Application Server V5.1 に関する基本的な知識のある方を対象にしています。これらのテクノロジーに関する理解を深めたい場合は、この記事の『参考文献』に入門用資料が用意されているのでご利用ください。IBM developerWorks で入手できる資料を参照することもおすすめします。
このシリーズのパート 1 およびパート 2、「サービスを介して資源にアクセス」および「WS-Resources のライフサイクルの管理」を読み、記事で使用する計算機の例についても理解しておいてください。
サンプル・コードの内容と要件
この記事で引用されるサンプルは、WebSphere Studio Application Developer V5.1.1 GM 版で作成されたものです。これらのサンプルは、WebSphere Application Server V5.1 に組み込まれたテスト環境において単体でテストされました。サンプルの WSDL は tcpmon ユーティリティーを使用するように構成されています。このユーティリティーは、交換される SOAP メッセージの監視用として Apache Axis に付属しています。リスン・ポートをポート 81 (listenPort) に設定し、要求を 9080 のターゲット・ポート (targetPort) に転送するように、tcpmon ユーティリティーを構成してください。tcpmon の詳細については、この記事の『参考文献』を参照してください。
ファイル ws-statefulws3code.zip には、この記事に収録されたコード・サンプルが含まれています。このファイルは、この記事の最上部または最下部にある「Code」アイコンをクリックするとダウンロードすることができます。このファイルには、次のファイルが含まれます。
WASv5WSAExtensions.jar
| SOAP メッセージの WS-Addressing メッセージ情報ヘッダーの作成時やアクセス時に WebSphere Application Server V5.1 によって必要とされる、ユーティリティー・クラスが含まれた JAR ファイル。WS-Addressing のエンドポイント・リファレンスを操作するためのヘルパー・クラスも含まれています。これらのクラスは、WebSphere Studio アプリケーションでの用途に応じて構成することができます。 |
WASvsWSAExtensions-javadoc.zip
| ユーティリティー・クラスの javadoc。 |
CalculatorService.ear
| ステートフルな計算機サービス (サンプル)。計算機サービスを簡単に呼び出すことのできる Web アプリケーションが用意されています。 |
計算機サンプル
このシリーズのパート 1 で紹介した計算機サンプルでは、標準の WSDL v1.1インターフェースを通じて、シンプルな計算機サービスがクライアント・プログラムに提供されました。このサービス・インターフェースでは、クライアントは計算機のインスタンスを作成した後、計算機の合計値に対して加算と減算を行うことができました。サンプル内では、計算機インスタンスは WS-Resource として扱われます。また、計算機 Web サービスの実装には、サービス・インターフェースをステートレス Session Bean として実装し、CMP Entity Bean に状態を保持する、既存の J2EE ベスト・プラクティスを使用することができました。
この記事では、WS-Resource Properties 仕様に記述されている技法を使用して、計算機の状態の構成要素をプロパティーとして選択的に公開する手順を、順を追って説明します。実際の作業は次のとおりです。
- 新たな属性 request を CalculatorState Bean に追加する。
- WS-Resource から公開されるプロパティーを表す XML スキーマを作成する。
- 作成したスキーマを計算機サービス WSDL に付加することにより、資源のプロパティーを計算機サービスと関連付ける。
- WS-Resource プロパティーに対する (実装予定の) アクセス・オペレーションが含まれるように、計算機サービス WSDL を更新する。
- 計算機サービス実装を拡張して、新しいオペレーションをサポートする。
この記事に記載された説明は、このシリーズのパート 1 で出てきたサンプル・コードを修正する際の参考になります。これらの修正を終えると、ws-statefulws3code.zip にあるようなコードが完成します。
CalculatorStateBean の修正
この例では、add、sub、および getTotal オペレーションを通じて資源へのアクセスが行われた回数を追跡するために、CalculatorState Bean を修正します。そのため、request という属性を CalculatorState Bean に追加します。さらに、add、sub、および getTotal メソッドに手を加えて、これらが呼び出されるたびに request カウンターが加算されるようにします。リスト 1 には、計算機サービスで修正された、add メソッドのコード・サンプルが含まれています。詳細については、CalculatorService.ear に含まれている CalculatorServiceSoapBindingImpl.java ファイルを参照してください。
リスト 1. add メソッドの実装
public float add(float value) {
float _newTotal = 0f;
try {
CalculatorStateLocalHome home = getCalculatorStateHome();
if (home != null) {
String calcID = getPrimaryKeyFromContext();
CalculatorStateLocal calculatorState =
home.findByPrimaryKey(calcID);
if (calculatorState != null) {
_newTotal = calculatorState.getTotal() + value;
calculatorState.setTotal(_newTotal);
}
//Increment the request counter
int request = calculatorState.getRequest();
calculatorState.setRequest(++request);
}
} catch (FinderException e) {
e.printStackTrace();
}
return _newTotal;
}
|
計算機 WS-Resource 用の資源プロパティー・ドキュメントの定義
WS-Resource Properties 仕様では、資源プロパティー・ドキュメントは、資源プロパティー要素の論理的構成を示す XML ドキュメントとして定義されています。資源プロパティー・ドキュメントでは、WS-Resource によって実装された状態データの特定のビューまたは射影が定義されます。計算機 WS-Resource には、calcid、request、および value の 3 つの資源プロパティーがあります。サンプルでは、これらのプロパティーを、計算機サービス経由で公開される WS-Resource のプロパティーとして公開します。公開するプロパティーは、実装の仕組みを説明するために、計算機サービスから任意に選択したものです。WS-Resource Properties 仕様では、どのプロパティーをサービスから公開すべきかについては規定されていません。時間が経てば、より高レベルなドメイン別仕様が発表され、資源プロパティーを公開する際のスタイルとベスト・プラクティス・パターンが定義されることでしょう。初期の例は、OASIS WSDM Technical Committee が作成した WS-Manageability 仕様に見られます (WS-Manageability および WSDM の詳細については、『参考文献』を参照)。
WS-Resource Properties 仕様に従い、WS-Resource を公開する Web サービスの WSDL 定義に、資源プロパティーのスキーマを追加する必要があります。リスト 2 に、計算機サービス WSDL に追加したスキーマを示します。詳細については、CalculatorService.ear に含まれている CalculatorService.wsdl ファイルを参照してください。
リスト 2. 計算機の資源プロパティーのスキーマ
...
<!-- Resource property element declarations -->
<element name="calcId" type="string"/>
<element name="total" type="float"/>
<element name="request" type="int"/>
<!-- Resource properties document declaration -->
<element name="GenericCalculatorProperties">
<complexType>
<sequence>
<element ref="intf:calcId"/>
<element ref="intf:total"/>
<element ref="intf:request"/>
</sequence>
</complexType>
</element>
...
|
リスト3 に示すように、WS-Resource Properties ドキュメントの宣言は、ResourceProperties 属性によって WSDL の portType 定義と関連付けられています。詳細については、CalculatorService.ear に含まれている CalculatorService.wsdl ファイルを参照してください。
リスト 3. 資源プロパティー・ドキュメントと portType の関連付け
...
<wsdl:portType name="CalculatorService" wsrp:ResourceProperties=
"intf:GenericCalculatorProperties">
...
|
計算機サービスへの WS-Resource Properties オペレーションの追加
- WS-Resource Properties:仕様には、メッセージ交換のコレクションが定義されています。このコレクションにより、リクエスターが資源プロパティーに対して値の取得、値の更新、クエリーの発行を行う際の手段が標準化されます。WS-Resource Properties 仕様に定義されている 4 つのオペレーションを次に示します。
- GetResourceProperty:このオペレーションでは、リクエスターは WS-Resource の単一の資源プロパティーの値を取得することができます。資源プロパティー・ドキュメントの型宣言を持つ portType を実装する Web サービスは、必ずこのオペレーションをサポートしている必要があります。
- GetMultipleResourceProperties:このオペレーションでは、リクエスターは WS-Resource の複数の資源プロパティーの値を取得することができます。このオペレーションのサポートはオプションです。
- SetResourceProperties:このオペレーションでは、リクエスターは WS-Resource の複数の資源プロパティーの値を修正することができます。このオペレーションで許可される変更には、挿入、更新、削除の 3 種類があります。このオペレーションのサポートはオプションです。
- QueryResourceProperties:このオペレーションでは、リクエスターは XPath などのクエリー式を使用して WS-Resource の資源プロパティー・ドキュメントを照会することができます。このオペレーションのサポートはオプションです。
この例では、GetResourceProperty と GetMultipleResourceProperties をサポートするように計算機サンプルを拡張します。今後の記事では、SetResourceProperties オペレーションと QueryResourceProperties オペレーションの実装について説明する予定です。リスト 4 は、GetResourceProperty オペレーションをサポートするために計算機サービスの WSDL に加えた修正です。WSDL で GetResourceProperty オペレーションをサポートするには、次の手順を実行します (他の WS-ResourceProperties オペレーションについても、これらの手順を繰り返してください)。
- WS-ResourceProperties スキーマを WSDL ドキュメントに貼り付けます。このスキーマには、BaseFaultType および GetRequestProperty の要求と応答の定義が含まれています。
- WS-Resource Properties 仕様の定義に従って、各種の障害に対する WSDL メッセージ、および GetRequestProperty の要求と応答に対する WSDL メッセージを追加します。
- CalculatorService portType に GetResourceProperty オペレーションを追加します。
- GetResourceProperty オペレーションのバインディング情報を、CalculatorService の SOAP バインディングに追加します。
WSDL には、実装予定のオペレーションのみを組み込んでください。そうすれば、すべてのサービス・リクエスターが、WSDL を手動またはプログラマチックにイントロスペクトする方法で、サポートされているオペレーションやアクセス可能なプロパティーを判別できます。他のオペレーションをサポートするために必要な変更については、CalculatorService.ear に含まれている CalculatorService.wsdl ファイルを参照してください。
リスト 4. 計算機サービスの WSDL に追加された GetResourceProperty オペレーション
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://calculator.samples.ibm.com" ...>
<wsdl:types>
<xsd:schema targetNamespace=
"http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceProperties" xmlns:wsrp=
"http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceProperties" ...>
<!-- ======= Global Attribute Declaration for WSDL 1.1 portType==== -->
<xsd:attribute name="ResourceProperties" type="xsd:QName"/>
<!-- ==== Common fault information to carry in all fault messages ==== -->
<xsd:complexType name="BaseFaultType">
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="Timestamp" type=
"xsd:dateTime"/>
<xsd:element maxOccurs="1" minOccurs="0" name="Originator" type=
"wsa:EndpointReferenceType"/>
<!--
<xsd:element name="ErrorCode"
minOccurs="0" maxOccurs="1">
<xsd:complexType>
<xsd:complexContent mixed="true">
<xsd:extension base="xsd:anyType">
<xsd:attribute name="dialect" type="xsd:anyURI"
use="required"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
-->
<xsd:element maxOccurs="unbounded" minOccurs="0" name=
"Description" type="xsd:string"/>
<xsd:element maxOccurs="unbounded" minOccurs="0" name=
"FaultCause" type="wsrp:BaseFaultType"/>
</xsd:sequence>
</xsd:complexType>
<!-- ========== Message Types for GetResourceProperty ============ -->
<xsd:element name="GetResourcePropertyRequest" type="xsd:QName"/>
<xsd:element name="GetResourcePropertyResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:any maxOccurs="unbounded" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="ResourceUnknownFaultType">
<xsd:complexContent>
<xsd:extension base="wsrp:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="ResourceUnknownFault" type="wsrp:ResourceUnknownFaultType"/>
<xsd:complexType name="InvalidResourcePropertyQNameFaultType">
<xsd:complexContent>
<xsd:extension base="wsrp:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="InvalidResourcePropertyQNameFault" type=
"wsrp:InvalidResourcePropertyQNameFaultType"/>
...
<wsdl:message name="InvalidResourcePropertyQNameFault">
<wsdl:part name="InvalidResourcePropertyQNameFault" element=
"wsrp:InvalidResourcePropertyQNameFault"/>
</wsdl:message>
<wsdl:message name="GetResourcePropertyResponse">
<wsdl:part name="GetResourcePropertyResponse" element=
"wsrp:GetResourcePropertyResponse"/>
</wsdl:message>
<wsdl:message name="GetResourcePropertyRequest">
<wsdl:part name="GetResourcePropertyRequest" element=
"wsrp:GetResourcePropertyRequest"/>
</wsdl:message>
<wsdl:message name="ResourceUnknownFault">
<wsdl:part name="ResourceUnknownFault" element=
"wsrp:ResourceUnknownFault"/>
</wsdl:message>
...
<wsdl:portType name="CalculatorService" wsrp:ResourceProperties=
"intf:GenericCalculatorProperties">
<wsdl:operation name="GetResourceProperty">
<wsdl:input name="GetResourcePropertyRequest" message=
"impl:GetResourcePropertyRequest"/>
<wsdl:output name="GetResourcePropertyResponse" message=
"impl:GetResourcePropertyResponse"/>
<wsdl:fault name="InvalidResourcePropertyQNameFault" message=
"impl:InvalidResourcePropertyQNameFault"/>
<wsdl:fault name="ResourceUnknownFault" message=
"impl:ResourceUnknownFault"/>
</wsdl:operation>
...
</wsdl:portType>
<wsdl:binding name="CalculatorServiceSoapBinding" type="impl:CalculatorService">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetResourceProperty">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="GetResourcePropertyRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="GetResourcePropertyResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="InvalidResourcePropertyQNameFault">
<wsdlsoap:fault name="InvalidResourcePropertyQNameFault" use="literal"/>
</wsdl:fault>
<wsdl:fault name="ResourceUnknownFault">
<wsdlsoap:fault name="ResourceUnknownFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
...
</wsdl:binding>
...
</wsdl:definitions>
|
リスト5 に、更新済みの WSDL を WSDL2Java ユーティリティーを通じて実行した後に得られるサービス・エンドポイント・インターフェース (SEI) を示します。
リスト 5. WS-ResourceProperties メソッドが含まれたサービス・エンドポイント・インターフェース
public interface CalculatorService extends Remote
{
public GetResourcePropertyResponse
getResourceProperty(QName getResourcePropertyRequest)
throws RemoteException,
InvalidResourcePropertyQNameFaultType,
ResourceUnknownFaultType;
public GetMultipleResourcePropertiesResponse getMultipleResourceProperties(
GetMultipleResourcePropertiesRequest getMultipleResourcePropertiesRequest)
throws RemoteException,
InvalidResourcePropertyQNameFaultType,
ResourceUnknownFaultType;
public SOAPElement
getCalculator(String accountName)
throws RemoteException;
public float
add(float value)
throws RemoteException;
public float
sub(float value)
throws RemoteException;
public float
getTotal()
throws RemoteException;
}
|
WS-Resource Properties オペレーションの実装と呼び出し
リスト6 に、計算機 Web サービスの GetResourceProperty メソッドの実装を示します。
リスト 6. 計算機 Web サービスの GetResourceProperty メソッドの実装
001 public com.ibm.samples.wsrp.GetResourcePropertyResponse
002 getResourceProperty(javax.xml.namespace.QName
003 getResourcePropertyRequest)
004 throws com.ibm.samples.wsrp.
InvalidResourcePropertyQNameFaultType,
005 com.ibm.samples.wsrp.ResourceUnknownFaultType
006 {
007 GetResourcePropertyResponse resourcePropertyResponse = null;
008
009 if((getResourcePropertyRequest != null)&&
010 011(getResourcePropertyRequest.getNamespaceURI().equals
011 (CALCULATOR_NS)))
012 {
013 try {
014 CalculatorStateLocalHome home =
015 getCalculatorStateHome();
016 if (home != null) {
017 String calcID = getPrimaryKeyFromContext();
018 CalculatorStateLocal calculatorState =
019 home.findByPrimaryKey(calcID);
020
021 String name =
022 getResourcePropertyRequest.getLocalPart();
023 SOAPFactory sf = new SOAPFactory();
024 SOAPElement[] se = new SOAPElement[1];
025 se[0] = (SOAPElement)
026 sf.createElement(name,
027 "calc",
028 CALCULATOR_NS);
029
030 if(name.equals("calcId"))
031 {
032 se[0].addTextNode(calcID);
033 resourcePropertyResponse = new
034 GetResourcePropertyResponse();
035 resourcePropertyResponse.set_any(se);
036
037 }
038 else if(name.equals("total"))
039 {
040 float total = calculatorState.getTotal();
041 se[0].addTextNode(
042 (new Float(total)).toString());
043 resourcePropertyResponse = new
044 GetResourcePropertyResponse();
045 resourcePropertyResponse.set_any(se);
046
047 }
048 else if(name.equals("request"))
049 {
050 int request = calculatorState.getRequest();
051 se[0].addTextNode(
052 (new Integer(request)).toString());
053 resourcePropertyResponse = new
054 GetResourcePropertyResponse();
055 resourcePropertyResponse.set_any(se);
056 }
057 else
058 {
059 String[] description
060 = {"Cannot find resource property"};
061 throw new
062 InvalidResourcePropertyQNameFaultType
063 (Calendar.getInstance(),
064 null,
065 description,
066 null);
067
068 }
069
070 }
071 } catch (FinderException e) {
072 e.printStackTrace();
073 String[] description = {"Cannot find resource"};
074 throw new ResourceUnknownFaultType
075 (Calendar.getInstance(),
076 null,
077 description,
078 null);
079 } catch (SOAPException e) {
080 e.printStackTrace();
081 }
082
083 }
084 else
085 {
086 String[] description
087 = {"Cannot find resource property"};
088 throw new InvalidResourcePropertyQNameFaultType
089 (Calendar.getInstance(),
090 null,
091 description,
092 null);
093 }
094 return resourcePropertyResponse;
095 }
096
|
上のコード・サンプルを詳しく見てみましょう。
- 行 9 から 11 では、getResourcePropertyRequest オブジェクトがヌルでなく、それに含まれるネーム・スペース URI が計算機サービスのネーム・スペース URI と一致することを確認します。
- 行 14 から 19 では、最初にリファレンス・プロパティーから calcID を取得し、それを使用して CalculatorState EJB ホームの findByPrimaryKey メソッドを呼び出して、CalculatorState Entity EJB コンポーネントの正しいインスタンスを検索します。
- 行 23 から 29 では、計算機サービスのネーム・スペースを使用して SOAP 要素を作成します。この SOAP 要素は、応答オブジェクト (resourcePropertyResponse) 内で送信されます。
- 行 30 から 37 では、getResourcePropertyRequest に含まれる名前が calcId かどうかを調べます。calcId である場合は、SOAP Element ノード (手順 3 でインスタンス化) の値を calcID (手順 2 で取得) に設定します。さらに、その SOAP 要素を resourcePropertyResponse 応答オブジェクトに設定します。
- 行 38 から 47 では、getResourcePropertyRequest に含まれる名前が total かどうかを調べます。total である場合は、CalculatorState EJB インスタンス (手順 2 で取得) から total の値を取得し、それを SOAP 要素に設定します。さらに、その SOAP 要素を resourcePropertyResponse 応答オブジェクトに設定します。
- 行 48 から 56 では、getResourcePropertyRequest に含まれる名前が request かどうかを調べます。request である場合は、CalculatorState EJB インスタンス (手順 2 で取得) から request の値を取得し、それを SOAP 要素に設定します。さらに、その SOAP 要素を resourcePropertyResponse 応答オブジェクトに設定します。
- 行 57 から 93 では、異なる例外 (WS-Resource Properties 仕様で定義) をスローします。
- 行 94 では、resourcePropertyResponse オブジェクトを返します。
リスト7 に、計算機 Web サービスが提供する GetResourceProperty オペレーションをクライアントが呼び出す方法を示します。詳細については、CalculatorService.ear に含まれている CalculatorTestExecute.jsp ファイルを参照してください。この例では、クライアントは、計算機 WS-Resource の total という名前の資源プロパティーを求めています。
リスト 7. 計算機の資源プロパティーへのアクセスを要求するサンプル・クライアント
com.ibm.samples.calculator.CalculatorService calculatorService = null;
// Initial Context
javax.naming.InitialContext ic = new javax.naming.InitialContext();
// Lookup calculator 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 calculator 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
{
String acctName = request.getParameter("acctName");
float add
= (new Float(request.getParameter("add"))).floatValue();
float sub
= (new Float(request.getParameter("sub"))).floatValue();
javax.xml.soap.SOAPElement SE
= calculatorService.getCalculator(acctName);
com.ibm.samples.wsa.wsaddr.EndpointReference epr
= com.ibm.samples.wsa.wsaddr.EndpointReference.fromSOAPElement(SE);
// Call JAXRPCHelper to associate EPR with account and
// make it stateful
com.ibm.samples.wsa.utils.JAXRPCHelper.setEPR(
(javax.xml.rpc.Stub) calculatorService ,
epr);
// Call a couple of other methods on calculator SEI
calculatorService.add(add);
calculatorService.sub(sub);
javax.xml.namespace.QName rpQName
= new javax.xml.namespace.QName("http://calculator.samples.ibm.com",
"total");
com.ibm.samples.wsrp.GetResourcePropertyResponse getResourcePropertyResponse
= calculatorService.getResourceProperty(rpQName);
javax.xml.soap.SOAPElement[] se1
= getResourcePropertyResponse.get_any();
...
|
GetResourceProperty 要求は Implied Resource パターンに従っています。つまり、ターゲットとなる暗黙的資源を識別するためにサービスが必要とする識別子の値は、WS-Addressing リファレンス・プロパティーに含まれています。これらは、SOAP ヘッダーの GetResourceProperty 要求メッセージに含まれていなければなりません。リスト 8 およびリスト 9 に、GetResourceProperty メッセージ交換の SOAP エンコーディングを示します。
リスト 8. GetResourceProperty 要求の SOAP
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc=
"http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd=
"http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing">
<wsa:To ...>
http://localhost:9080/CalculatorServiceWeb/services/CalculatorService
</wsa:To>
<calcID ...>
1083949184296
</calcID>
<dummyProp...>
EXAMPLE PROPERTY
</dummyProp>
</soapenv:Header>
<soapenv:Body>
<GetResourceProperty xmlns="">
<GetResourcePropertyRequest xmlns:ns-1495319864=
"http://calculator.samples.ibm.com" xmlns=
"http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceProperties">
ns-1495319864:total
</GetResourcePropertyRequest>
</GetResourceProperty>
</soapenv:Body>
</soapenv:Envelope>
|
リスト 9. GetResourceProperty 応答の SOAP メッセージ
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc=
"http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd=
"http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<GetResourcePropertyResponse xmlns="">
<GetResourcePropertyResponse xmlns=
"http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceProperties">
<calc:total xmlns:calc="http://calculator.samples.ibm.com">5.0</calc:total>
</GetResourcePropertyResponse>
</GetResourcePropertyResponse>
</soapenv:Body>
</soapenv:Envelope>
|
リスト10 に、計算機 Web サービスの GetMultipleResourceProperties メソッドの実装を示します。詳細については、CalculatorService.ear に含まれている CalculatorServiceSoapBindingImpl.java ファイルを参照してください。実装では、getResourceProperty オペレーションを N 回呼び出しています。ここで、N は getMultipleResourcePropertiesRequest に含まれる QName 配列と同じサイズです。各呼び出しの結果は、SOAP 要素の配列に収集された後、resourcePropertiesResponse に設定されます。これがクライアントに返されます。
リスト 10. GetMultipleResourceProperties オペレーションの実装
public com.ibm.samples.wsrp.GetMultipleResourcePropertiesResponse
getMultipleResourceProperties
(com.ibm.samples.wsrp.GetMultipleResourcePropertiesRequest
getMultipleResourcePropertiesRequest)
throws com.ibm.samples.wsrp.InvalidResourcePropertyQNameFaultType,
com.ibm.samples.wsrp.ResourceUnknownFaultType
{
QName[] resourceProperty
= getMultipleResourcePropertiesRequest.getResourceProperty();
int size = resourceProperty.length;
SOAPElement[] se = new SOAPElement[size];
GetMultipleResourcePropertiesResponse resourcePropertiesResponse
= null;
if((resourceProperty != null)&&( size!= 0))
{
for(int i=0; i<size; i++)
{
SOAPElement[] _se
= getResourceProperty(resourceProperty[i]).get_any();
se[i] = _se[0];
}
resourcePropertiesResponse
= new GetMultipleResourcePropertiesResponse();
resourcePropertiesResponse.set_any(se);
}
return resourcePropertiesResponse;
}
|
リスト11 に、計算機 Web サービスが提供する GetMultipleResourceProperties オペレーションをクライアントが呼び出す方法を示します。詳細については、CalculatorService.ear に含まれている CalculatorTestExecute.jsp ファイルを参照してください。この例では、クライアントは計算機 WS-Resource の 2 つの資源プロパティー (total および request) を求めています。
リスト 11. 計算機の資源の複数プロパティーへのアクセスを要求するサンプル用クライアント
com.ibm.samples.calculator.CalculatorService calculatorService = null;
// Initial Context
javax.naming.InitialContext ic = new javax.naming.InitialContext();
// Lookup calculator 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 calculator 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
{
String acctName = request.getParameter("acctName");
float add
= (new Float(request.getParameter("add"))).floatValue();
float sub
= (new Float(request.getParameter("sub"))).floatValue();
javax.xml.soap.SOAPElement SE
= calculatorService.getCalculator(acctName);
com.ibm.samples.wsa.wsaddr.EndpointReference epr
= com.ibm.samples.wsa.wsaddr.EndpointReference.fromSOAPElement(SE);
// Call JAXRPCHelper to associate EPR with account and
// make it stateful
com.ibm.samples.wsa.utils.JAXRPCHelper.setEPR(
(javax.xml.rpc.Stub) calculatorService ,
epr);
// Call a couple of other methods on calculator SEI
calculatorService.add(add);
calculatorService.sub(sub);
...
com.ibm.samples.wsrp.GetMultipleResourcePropertiesRequest
getMultipleResourcePropertiesRequest =
new com.ibm.samples.wsrp.GetMultipleResourcePropertiesRequest();
javax.xml.namespace.QName[] resourceProperty
= new javax.xml.namespace.QName[2];
resourceProperty[0] = new javax.xml.namespace.QName(
"http://calculator.samples.ibm.com",
"total");
resourceProperty[1] = new javax.xml.namespace.QName(
"http://calculator.samples.ibm.com",
"request");
getMultipleResourcePropertiesRequest.setResourceProperty(
resourceProperty);
com.ibm.samples.wsrp.GetMultipleResourcePropertiesResponse
getMultipleResourcePropertiesResponse =
calculatorService.getMultipleResourceProperties(
getMultipleResourcePropertiesRequest);
javax.xml.soap.SOAPElement[] se
= getMultipleResourcePropertiesResponse.get_any();
...
|
GetMultipleResourceProperties要求も、Implied Resource パターンに従っています。リスト 12 およびリスト 13 に、GetResourceProperty メッセージ交換の SOAP エンコーディングを示します。
リスト 12. GetMultipleResourceProperties 要求の SOAP
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc=
"http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd=
"http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing">
<wsa:To ...>
http://localhost:9080/CalculatorServiceWeb/services/CalculatorService
</wsa:To>
<calcID ...>
1083949184296
</calcID>
<dummyProp...>
EXAMPLE PROPERTY
</dummyProp>
</soapenv:Header>
<soapenv:Body>
<GetMultipleResourceProperties xmlns="">
<GetMultipleResourcePropertiesRequest xmlns=
"http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceProperties">
<ResourceProperty xmlns:ns-1495319864=
"http://calculator.samples.ibm.com" xmlns=
"">ns-1495319864:total</ResourceProperty>
<ResourceProperty xmlns:ns-1495319864=
"http://calculator.samples.ibm.com" xmlns=
"">ns-1495319864:request</ResourceProperty>
</GetMultipleResourcePropertiesRequest>
</GetMultipleResourceProperties>
</soapenv:Body>
</soapenv:Envelope>
|
リスト 13. GetMultipleResourceProperties 応答の SOAP メッセージ
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc=
"http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd=
"http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<GetMultipleResourcePropertiesResponse xmlns="">
<GetMultipleResourcePropertiesResponse xmlns=
"http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceProperties">
<calc:total xmlns:calc="http://calculator.samples.ibm.com">5.0</calc:total>
<calc:request xmlns:calc="http://calculator.samples.ibm.com">4</calc:request>
</GetMultipleResourcePropertiesResponse>
</GetMultipleResourcePropertiesResponse>
</soapenv:Body>
</soapenv:Envelope>
|
結論
この記事では、サービス・リクエスターが WS-Resource プロパティーの定義およびアクセスをどのように行うかについて基本的な説明を加えました。説明では、J2EE ベスト・プラクティスを利用した基本サービス実装を簡単に拡張することで、新しいアクセサー・オペレーションをサポートできることを示しました。特に、プロパティー・ドキュメントで定義された QName を、その状態が含まれる EJB Entity Bean フィールドにシンプルにマッピングする方法を示しました。同様に、既存のツールを利用してこの実装を簡単に実現できることも示しました。
この分野に投入されるテクノロジーが増えていくにつれて、WS-Resource プロパティーによって導入されるオプションのオペレーションは、ますます簡単に実装できるようになるでしょう。特に、WS-transactions と Set オペレーションを組み合わせれば、セマンティクスを新しくするために、より多くの構造と定義を得られると考えられます。また、XMLBeans や Service Data Objects などの新しいテクノロジーの登場は、XPATH の表現力をより活かすことにつながります。これらの構造を利用した構成体を使って照会オペレーションを実装することは、今後のプロトタイプ化に向けた興味深いテーマです。
Acknowledgements
The author wishes to thank Sonny Fulkerson for reviewing this article and for providing technical guidance.
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| ws-statefulws3code.zip | ws-statefulws3code.zip | |
FTP |
|---|
参考文献
- Read the other parts of the series "Implement and access stateful Web services using WebSphere Studio:"
- Get the JAX-RPC specification from the Java Community Process.
- For more information on J2EE Web services, check out Part 1 and Part 2 of Greg Flurry's series, "Support for J2EE Web Services in WebSphere Studio Application Developer V5.1" (developerWorks, October 2003).
- Check out JSR 109, which covers Web services for J2EE environment.
-
Download the WS-Addressing specification from IBM developerWorks. WS-Addressing is an XML serialization and standard SOAP binding for representing network-wide pointers to services.
- Get the specifications related to the WS Resource Framework, which are: WS-Notification,WS-ResourceProperties, WS-ResourceLifetime.
- Find the family of WS-Notification specifications, which include: WS-BaseNotification, WS-BrokeredNotification, and WS-Topics.
- Check out the OASIS Web site for more information on the OASIS WSDM Technical Committee. Also refer to the
documents section
.
- Check out Apache XMLBeans.
- Obtain more information on tcpmon from the Axis User’s Guide.
- Download the Service Data Objects specification from IBM developerWorks.
- 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)
- Access Web services knowledge, tools, and skills with Speed-start Web services, which offers the latest Java-based software development tools and middleware from IBM (trial editions), plus online tutorials and articles, and an online technical forum.
- 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.
著者について  | |  | Hidayatullah H. Shaikh is a senior software engineer on the IBM Software Group On-Demand Architecture and Development Team. His areas of interest and expertise include business process modeling and integration, service-oriented architectures, grid computing, e-commerce, J2EE technology, and database management (DBMSs) technologies. You can contact Hidayatullah at hshaikh@us.ibm.com. |
記事の評価
|  |