ドキュメント指向のサービスのデザイン
Sean Brydon、Smitha Kangath、Sameer Tyagi
課題
J2EE[tm] プラットフォーム (Java[tm] 2 Platform, Enterprise Edition) 1.4 アプリケーションで、JAX-RPC (Java API for XML-based RPC) を利用した XML ドキュメントの引き渡しが必要になることがあります。たとえば、アプリケーションに PurchaseOrder.xml あるいは Invoice.xml ドキュメントを受け付けるサービスがある場合などです。こうした問題の解決策として、ここでは、サービスでドキュメント処理の問題をモデリングする、ドキュメント利用のサービスについて説明します。手続きを用いたサービスではなく、ドキュメントを用いたサービスに焦点を当てます。開発者は、事前に取り決められた XML スキーマに準拠した XML ドキュメントの形式でデータが交換される Web サービスの作成が必要になることがあります。そうしたスキーマは個々のアプリケーションに固有のこともあれば、垂直的な業界規格団体によって定義されることもあります。ここでは、XML ドキュメントの同期あるいは非同期処理の区別をしません。処理モデルに関係なく、単に XML ドキュメントの引き渡しに焦点を当てます。この解決策は、どちらの種類のサービス処理モデルにも適用できます。デザイン上の選択肢で重要なことの 1 つは、交換される XML ビジネスドキュメントの記述に使用するインタフェースアーティファクトの型を決定することです。
クライアントとサービスが XML ドキュメントを交換する Web サービスとの対話のデザインでは、サービスインタフェース内の XML ドキュメントを記述する型を選択する必要があります。パラメータまたは戻り値として交換される XML ドキュメントの型は、サービスの WSDL と、サービスの Java インタフェースおよび実装クラスで表明します。PurchaseOrder.xml のような XML ドキュメントを受け取るサービスのデザインでは、インタフェースおよび WSDL ファイルにおいて、XML ドキュメントを記述する型を選択する必要があります。たとえば、注文書 XML ドキュメントの型として文字列を使用したり、オブジェクトの形式で、すべてのドキュメント詳細およびスキーマ詳細の記述をインタフェースに埋め込んだり、xsd:anyType などの型を選択することによって XML フラグメントで注文書を表したりできます。その他にも選択肢はありますが、いずれにしても、サービスのデザインでは、この型の選択が重要です。
サービスインタフェースの XML ドキュメントを記述する型の選択は、多くのことに影響します。たとえば、サーバー側では、WSDL ファイル内のパラメータ (および戻り値) の型変更や、Java インタフェースおよび実装クラス内のパラメータの型変更、さらには、ドキュメントの妥当性検査や XML から Java オブジェクトへのバインドなど、受け取ったドキュメント処理の変更が必要になります。同様に、サービスのクライアント側も、サービスのインタフェースおよび WSDL における、デザイン時の XML を記述する型の選択の影響を受けます。たとえば、交換する XML ドキュメントのパラメータを作成する必要があるため、クライアントコードの変更が必要になり、これはシリアライズされたドキュメントの特性に影響します。また、ドキュメントが戻されるときの、受信ドキュメントの処理方法も影響を受けます。こうしたことは、サービスインタフェースで交換される XML ドキュメントを記述する型を選択する際に開発者が考慮する必要があることです。
また別の考慮事項として、環境によっては、サービス、特に SOAP 層でサービスに対して管理あるいは監視ツールが使用されることがあり、その場合、型によっては、監視ツールから見えにくいものがあります。たとえば文字列は、エンコーディングでその表現に追加情報が含まれるため、ツールによる処理が難しいことがあります。このため、送信レベルでの署名の見え方が監視機能に影響する可能性があります。当然のこととして、相互運用性も、伝達されるパラメータ型の選択の影響を受ける可能性があり、これも考慮事項の 1 つです。
ここでの対処法は、次の状況で適用できます。
- 交換するデータが XML ドキュメントの形式の Web サービスを作成する必要がある。
- Web サービスと、ドキュメントを用いるほかのアプリケーションを統合する必要がある。
- Web サービスとの対話に JAX-RPC などの J2EE 1.4 テクノロジを利用する。
- Java-to-WSDL (Java インタフェースで開発してから WSDL を生成する手法) あるいは WSDL-to-Java (WSDL を開発してから Java インタフェースを生成する手法) いずれかの開発手法を利用する。
対処法
クライアントとサービスが XML ドキュメントを交換する Web サービスとの対話のデザインでは、サービスインタフェース内の XML ドキュメントを記述する型を選択する必要があります。サービスインタフェースの XML ドキュメントを記述する型の選択は、多くのことに影響します。
ここでは、これまでに示したいくつかの対処法を簡単に要約、比較し、対処法を選択する際の指針を提供します。焦点は XML 対話層にあり、XML ドキュメントのビジネス処理にはありません。これらの対処法についてはそれぞれ、カタログ内の別の関連するエントリで詳しく説明しているため、それら関連するエントリおよびアプリケーションにも目を通してください。サンプルアプリケーションとともに次の対処法が取り上げられています。
SOAP 本体での base64Encoded あるいは raw バイトの使用、データバインドなしの使用など、ほかの対処方法が後日追加される可能性もあります。
一部ですが、この課題と対処法に関わる要素を簡単にまとめると次のようになります。
- サービスに Web サービス要求を行うクライアント。クライアントは、XML ドキュメントを作成してサービスの WSDL に定義されている適切な型に変換し、クライアント側で XML ドキュメントをサービスに渡してサービスを呼び出す Java メソッドを呼び出す必要があります。
- XML ドキュメントは、たとえば注文書の内容などの、引き渡すペイロードです。
- サービス記述用の WSDL ファイル
- サービスエンドポイントインタフェースクラス。サービスの Java インタフェースとなるクラスです。
- サービスエンドポイント実装クラス。JAX-RPC エンドポイントか EJB エンドポイント実装クラスのいずれかになります。
- XML ドキュメントに対して選択されたパラメータおよび戻り値の型。この型は、サービス記述用の WSDL ファイルと、サービスエンドポイントインタフェースクラス、サービスエンドポイント実装クラスに反映されます。
- XML ドキュメントのシリアライズ (on the wire) 表現
クライアントと Web サービス間で交換される XML ドキュメントを記述する型の選択は、これら関係要素のすべてに影響することがあります。たとえば、サービス実装によって生成されたすべての Java クラスに反映されるよう、選択した型は、ファイルの WSDL ファイルに含める必要があり、これは、Web サービス層を追加するアプリケーションの既存のオブジェクトモデルにも影響することがあります。クライアントアプリケーションは、サービスの WSDL ファイルに定義されている型に応じて Java クラスを生成し、自身のクライアントデータモデルをサービスの型に変換する必要があるため、サービスにアクセスするクライアントアプリケーションも影響を受けます。この型の選択は、サービスの相互運用性にも影響することがあります。また、JAX-RPC 実行時環境が Java オブジェクトへのバインドを行えるかどうか、あるいはアプリケーションコードが代わりにこのバインドを行う必要があるかどうかにも関係することがあります。
推奨とまとめ
サービスインタフェースに対する型を選択するにあたっては、以下のことを推奨します。
- 多くの場合、サービスにはスキーマ定義型を使用することを推奨します。これが最も一般的です。大部分のサービスには、サービスに渡し、サービスが返す XML ドキュメントに対して綿密に定義された型があります。WSDL ファイルおよび関係するスキーマファイルでサービスがより完全に記述されるため、この対処法はうまく機能します。この対処法は、ドキュメントを記述する型として文字列型を使用する方法と対比されます。これは 文字列型を使用する方法では、サービスと交換される XML ドキュメントのスキーマに関する情報が隠されるためです。たとえば、purchaseorder.xml ドキュメントを受け付けるメソッドがサービスに必要で、文字列型を使用した場合、サービスの記述は WSDL ファイル内の文字列 1 つだけで、このサービスが予測するドキュメントに関する情報が得られません。このため、クライアントがサービスを利用するのが難しくなります。スキーマ定義型を使用することのもう 1 つの利点は、JAX-RPC 実行時環境を使用して、Java オブジェクトにバインドできるため、その分、アプリケーションのコーディングの手間を省けることです。
- 仲介サービス、すなわち、ブローカサービスを開発する場合は、交換される XML ドキュメントを xsd:any を使って記述するようにサービスをデザインすることを推奨します。この場合、サービスは、多くの種類のドキュメントを受け付ける汎用的なサービスメソッドを作成します。
- アタッチメントは、たとえば、大きな画像を交換する場合など、XML ドキュメントを SOAP メッセージ内のペイロードに含めない場合に有用です。ただし、この対処法は、今日の多くのシステムで相互運用性がないことに注意してください。
- 交換する XML ドキュメントを文字列型で記述する方法は回避することを推奨します。
表 1 は、ドキュメント指向の Web サービスで交換される XML ドキュメントを記述する型を選択する際のさまざま考慮事項をまとめています。Java BluePrints Solutions Catalog のそのほかのエントリでも、これらの項目についてさらに詳しく取り上げています。
対処法
|
長所
|
短所
|
スキーマ定義型 (doc-literal 形式)
|
- 相互運用性
- XML ドキュメントが使用された場合のスキーマとの照合
- エンコーディングされた書式スタイルよりパフォーマンスに優れる
|
- カスタムバインドやバインドフレームワークを直接には使用できない
- 予想されるドキュメントの型がサービスインタフェースで明確に記述されるため、クライアントにとって、WSDL ファイルが理解しやすくなる。
|
文字列型
|
- hello world アプリケーションと同じで単純
|
- 実行時環境の提供するスキーマ検査を利用できず、サービスがメモリー上のドキュメントを読み取り、処理するまでドキュメントのエラーが発見されない。
- ドキュメントの型が単に一般的な文字列であるため、サービスインタフェースが記述的でない。
|
xsd:any
|
- xsd:any のマッピングが標準化されていて、JAX-RPC 1.1 を使って SOAPElement にマッピングできる。
要素名 (BusinessDocumentRequest など) が WSDL に指定されていて 、渡されたビジネスドキュメントがそれら要素内に現れたとしても、Web サービスおよびそのクライアントは、それらの要素の下にあるものとしてドキュメントの内容を取り込まなくても、完全な XML ドキュメントを操作し、スキーマの整合性を維持できる (これは、anyType を使用する方法では不可能)。
|
- SOAPElement オブジェクトの作成、操作の作業が必要なため、XML の下位レベルでの作業が必要になる。
- ドキュメントを定義しているスキーマが直接には参照されないため、WSDL とドキュメントの間のつながりがない。
- 帯域外でスキーマの取り決めを行う必要がある。予想されるドキュメントのスキーマを WSDL ファイルで記述しないため、サービスの提供側と消費側の両方で、ペイロードの内容に関する情報がアプリオリに必要である。
|
xsd:anyType
|
- アクションとペイロードを一緒に渡すことが可能で、これは、同じアクションで複数の種類のドキュメントを受け付ける異種文書プロセッサ、たとえば、準拠するスキーマが異なる注文書と請求書の両方に検索アクションを実行する 1 つのサービスなどを作成する場合に役立つことがある。
|
- JAX-RPC 仕様に、xsd:anyType の標準的な Java マッピングが定義されていないため、必ずしもすべての実装が Java WSDP のような動作をせず、SOAPElement にマッピングされない。実際には、実装では、xsd:anyType のサポートは任意である。
- 実際には anyType は WSDL 内に名前が指定された要素に対するデータ型の定義であるため、SOAP 本体で渡されるビジネスドキュメントは、WSDL で定義されたこの要素内に置かれる (たとえば、PurchaseOrder は BusinessDocumentRequest 要素内に置かれる)。このことは、渡されるドキュメントが次のいずれかの条件を満たす必要があることを意味する。
- ドキュメントのルート要素が WSDL 内に定義されている。
- ドキュメントを適宜作成するか、その場で要素内にラップする。
|
アタッチメント
|
- Web サービスがサポートしていない言語で表現されたスキーマに準拠するか、SOAP メッセージ情報セット (DTD に基づくスキーマの文書型宣言 <!DOCTYPE> など) に含めることができないドキュメントに有用。
- 大きなドキュメント (圧縮/圧縮解除可能なドキュメント) に有用。
- ハンドラを使用し、追加機能をアタッチメントに付加することが可能。たとえば、パスワードを用いた独自の暗号化をアタッチメントに追加し、GZIP アルゴリズムを使ってそのアタッチメントを圧縮するクライアント側ハンドラなどを追加できる。対応するサーバー側ハンドラは、添付の内容を圧縮解除し、暗号化アルゴリズムに基づき、同じパスワードを使って暗号を解読する。
|
- 相互運用性: アタッチメントをサポートしていないベンダーがある。たとえば .NET は、拡張バックがあるものの独自の機構を使用し、WS-I アタッチメントプロファイルに基づく MIME 添付を処理できない。
|
表 1: さまざまな対処法の比較
表 1 にまとめた対処法に加えて、状況に応じて使用可能な、それら対処法のバリエーションやそのほかの対処法もあります。たとえば、JAX-RPC のバインド機構を利用することが望ましくなく、データバインドをいっさい利用しない状況も考えられます。これは、JAXB のような API と統合し、それにバインドを行わせる場合に有用です。こうした手法の欠点は、動作が実行時環境に固有のものになる点です。たとえば、Java Web Services Developer Pack では、nodatabinding
スイッチがサポートされているが、ほかの実装では、そうした機能がサポートされていないことがあります。試すことができるもう 1 つのバリエーションとして、base64 エンコーディングの利用もあります。これは、SOAP メッセージ情報セットと実行時実装のどちらもサポートしていない文字あるいは宣言が XML に含まれている場合に役立つ可能性があります。たとえば、DTD 宣言やロケール固有の文字エンコーディングなどがこれにあたります。ただし、これには相互運用性の問題があることに注意してください。これらの他にも選択肢はありますが、一般には、「推奨とまとめ」のガイドラインに従うのが最善です。
参考資料
このドキュメントで取り上げたさまざまな対処法の詳細な説明、およびサンプルアプリケーションなど、この項目に関する詳細は、次の資料を参照してください。
© Sun Microsystems 2005. All of the material in The Java BluePrints Solutions Catalog is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.