このように、新しい「Web サービスビュー」をアプリケーションに追加することで、同じビジネスロジックとフレームワークを使用しながら、既存のエンタープライズアプリケーションから Web サービスを作り出すことができます。
Web サービス要求の処理
Web サービスは、クライアントからの要求に応答します。Web サービスは XML 標準に基づくテクノロジを通じて利用可能なため、着信するすべての要求は XML ドキュメントです。着信 XML ドキュメントは事前処理し、必要に応じて、内部で理解できるフォーマットに変換してから、それに含まれる情報を取得するための処理をしなければなりません。また、要求を処理する前にすべてのセキュリティチェックを実行する必要があります。これらを行う際に注意すべき点がいくつかあります。
事前処理と変換:着信 XML ドキュメントは、最初に事前処理して、必要に応じて、Web サービスが理解できる共通内部フォーマットに変換しなければなりません。同じサービスに対する異なるクライアントからの異なる形式の要求に対応するときであっても、要求の処理時に共通内部フォーマットを使用して Web サービスを使用可能にする必要が生じる場合があります。
たとえば、オンライン請求サービスを提供する Web サービスを考えてみてください。このサービスは、顧客からユーザ情報、口座情報、および支払情報を取得する場合があります。これらの情報を受け取る際、実際の支払トランザクションを完了する前に適切な認証やセキュリティチェックを行う必要があります。異なる顧客のニーズを満たすには、Web サービスプロバイダは、次に示すように 2 つの異なる形式の要求を受け取ることに同意する必要があります。
<BillingRequest>
<CustomerName>customer1</CustomerName>
<CustomerId>1234</CustomerId>
<UserDetails>
<Name>John Doe</Name>
<AcctNo>12345678</AcctNo>
<PIN>9999</PIN>
</UserDetails>
<PaymentDetails>
<BankName>Some Bank</BankName>
<RoutingNo>12345678901234</RoutingNo>
<Amount>1234.12</Amount>
</PaymentDetails>
</BillingRequest>
リスト 1:請求要求フォーマット - 1
<BillingRequest>
<CustomerName>customer2</CustomerName>
<CustomerId>6789</CustomerId>
<Details>
<BankName>Some Bank</BankName>
<AcctNo>12345678</AcctNo>
<RoutingNo>12345678901234</RoutingNo>
<PIN>9999</PIN>
<Amount>1234.12</Amount>
</Details>
</BillingRequest>
リスト 2:請求要求フォーマット - 2
オンライン請求サービスの使いやすさと柔軟性を高めるために、これら 2 つの異なる形式の要求を処理する方法を採用する場合があります。同じサービスに対する 2 つの異なる形式の要求を受け取る理由が何であるにせよ、顧客の要求するトランザクションを完了するのに、請求サービスは口座情報、ルーティング情報、および支払情報しか必要としません。そのような場合、異なる形式の要求をやりとりする代わりに、請求サービスが共通内部フォーマットに従ってそれ以降の処理を行った方がずっと簡単です。この共通内部フォーマットとは、次に示す XML ドキュメントのようなものです。
<BillingRequest>
<CustomerId>6789</CustomerId>
<AcctNo>12345678</AcctNo>
<PIN>9999</PIN>
<RoutingNo>12345678901234</RoutingNo>
<Amount>1234.12</Amount>
</BillingRequest>
リスト 3:請求要求の共通内部フォーマット
共通内部フォーマットは、プロセスを単純かつ明確なものにします。Web サービスプロバイダは、要求を事前処理し、必要なすべての情報が揃っていることを確認して、共通内部フォーマットに変換する必要があります。Web 層でこの事前処理と変換を行うのは良い方法です。着信要求に含まれるエラーを要求を処理する前に発見できるからです。これによって、時間を節約でき、ビジネスロジックが常駐する EJB 層への不要な移動をしないで済みます。要求の共通内部フォーマットを 1 つにすることで、ビジネスロジックが異なる要求フォーマットについて知る必要がなくなります。これによって、アプリケーションは緩やかに結合され、他の新たな顧客の異なる要求フォーマットを追加するのが非常に容易になります。JAXP API の XSLT 機能は、この事前処理と変換のために効率的に使用できます。
セキュリティ:着信要求の事前処理に伴い、セキュリティについても Web 層にて Web サービスによって管理されなければなりません。セキュリティを確保するには、SSL が最適です。さらに、各要求にユーザ名とパスワードも含める必要があるかも知れません。セキュリティを確保するもう 1 つの方法は、J2EE プラットフォームのフォームベースログイン機構を介して、Web サービスの顧客をオフラインで登録してオンラインアクセスを許可するという方法です。
ドキュメントの処理:ユーザが認証されてドキュメントが検証されると、次のステップは XML ドキュメントのコンテンツを処理することです。XML ドキュメントの処理は、DOM と SAX という 2 つの方法で行うことができます。Java APIs for XML Processing (JAXP) は、両方の処理方法をサポートします。Document Object Model (DOM) API は、XML ドキュメントを、情報を取得するのに走査できるツリーに変換します。SAX API は、XML ドキュメントを一連のイベントに変換して、ユーザ定義ハンドラに処理させます。図 2 は、SAX と DOM の処理を図示したものです。
次に Web サービス実装側が XML ドキュメントを解析するのにどちらの処理方法を使用するかを決定する際に注意すべき点を示します。
DOM による処理:DOM による XML の処理には、大きなメモリと帯域幅が必要です。しかし、DOM API を使用したプログラミングは、非常に簡単です。これは、API が効率的な構築方法を提供することに加えて、ツリーを走査するからです。JDOM や DOM4J のような、DOM よりも上位の API を利用できるので、DOM の解析は一層簡単になります。特に、要求の処理中に XML ドキュメントを変更する場合に DOM は役に立ちます。これは、DOM ツリーとして表現される XML ドキュメントのコンテンツを追加、削除、または修正するのが簡単なためです。XML ドキュメントの DOM ツリーを構築して使用するときは、同じ VM 内で行うのが好まし方法です。その他のシステムまたは VM とやりとりする場合は、DOM ではなく XML ドキュメントとしてドキュメントをやりとりする方が良いでしょう。これは、大容量の DOM オブジェクトを直列化することは負荷が高いためです。さらに、Web サービス要求がワークフローをトリガする場合、着信 XML ドキュメントを論理的な DOM フラグメントに分けて、該当するフラグメントをワークフローの対応する部分に引き渡す方が良いかも知れません。このようにすると、ワークフローのさまざまな部分で完全な XML ドキュメントを不要に処理する頻度を減らすことができます。
たとえば、次に示すような XML ドキュメントを考えてみてください。この要求は、注文処理センターの機能を提供する Web サービスから送られてきます。XML ドキュメントには、顧客の注文を処理するのに必要な、ユーザ、注文、品目、出荷などに関するすべての詳細情報が含まれています。この XML ドキュメントは大容量だと仮定します。
<CustomerOrder>
<UserDetails>
<Name>John Doe</Name>
<UserId>doedoe</UserId>
<CredirCard>4354543545</CreditCard>
<CardType>VISA</CardType>
<Expiry>10/2005</Expiry>
<!-- Other User information -->
</UserDetails>
<OrderDetails>
<OrderId>1234</OrderId>
<OrderType>URGENT</OrderType>
<!-- Other Order information -->
</OrderDetails>
<ItemDetails>
<ItemName>some item</ItemName>
<ItemId>KJ3423</ItemId>
<!-- Other Item information -->
</ItemDetails>
<ShippingDetails>
<Name>John Doe</Name>
<Street>1234, some street</Street>
<!-- Other Address information -->
</ShippingDetails>
</CustomerOrder>
リスト 4:注文の詳細情報を含む XML ドキュメント
注文を処理するのに、Web サービスは完結したワークフローを実装しなければなりません。たとえば、この Web サービスは、ユーザのクレジットカードの承認を取得し、注文品が供給可能かどうか確認し、注文処理を確約して、品物を出荷しなければなりません。XML ドキュメントは、ワークフロー全体が完了するまで必要です。この XML ドキュメントを DOM を使用して処理すること、つまりDOM ツリーを作成してワークフロー全体を通じて使用することは理にかなっています。また、ワークフローのステータスを XML ドキュメントの一部として保存しても良いでしょう。この場合でも DOM ツリーを修正するのが簡単なので、DOM が理想的となります。このワークフローが、異なる VM で配信された Enterprise JavaBeans の使用または他の Web サービスの使用を通じて実装される場合、この大容量のドキュメントを、ユーザの詳細を表現するフラグメント、注文の詳細を表現するフラグメント、といった具合に論理的なフラグメントに分けるのが効果的です。これらのフラグメントは、個々のワークフロー実装側に送付して処理してもらいます。これによって、XML ドキュメント全体を異なる複数の場所で不要に処理するのを避けることができます。
要求を処理する際にもう 1 つ注意すべき点は、ドキュメント内の情報が確実に必要となるときまで XML ドキュメントを 1 つのドキュメントとして維持しておくことです。これは、1 つのワークフローにおいて、すべての段階でドキュメントを完全に理解する必要はないからです。前述の例では、Web サービスは実際のワークフローを開始する前にいくつかの予備チェックを実行しなければならない場合があります。予備チェックに失敗すれば、ワークフロー自体が開始されない可能性があります。そのような場合、ドキュメントを処理するのに費やした時間が無駄になってしまいます。したがって、ドキュメントから情報をどうしても取得しなければならなくなるまで、ドキュメントは受け取ったままの状態にしておいた方が良いでしょう。
SAX による処理:SAX による XML の処理では、XML ドキュメントのコンテンツへ順次アクセスします。この XML ドキュメントの処理方法は、非常に高速です。しかし、SAX を使用してのプログラミングは複雑です。一度だけ読み込み、いくつかのアクションを受け取り、変更を加えないような XML ドキュメントに対して SAX は最適かも知れません。たとえば、設定情報を含む次のような XML ドキュメントを考えてみてください。この XML ドキュメントは大容量であると仮定します。
<ConfigInfo>
<ServerName>someserver</ServerName>
<ServerPort>7000</ServerPort>
<Protocol>HTTPS</Protocol>
<Login>YES</Login>
<!-- Other configuration information -->
</ConfigInfo>
リスト 5:詳しい設定情報を含む XML ドキュメント
この XML ドキュメントは、サービス要求者の設定内容を理解するのに Web サービスが使用するものである場合があります。この設定情報は、要求を処理して応答する際に使用される場合があります。このような設定情報は、Web サービスによって一度だけ使用され、保存する必要がない点に注目します。この情報は Web サービスによって変更されることはありません。したがって、このような場合、SAX が提供する処理速度を有効に活用でき、DOM による処理のメリットがないので、SAX による処理が理想的な処理方法となります。
Web サービスによる応答の生成
要求の処理後は、応答のコンテンツの生成です。着信要求と同様に、応答も XML ドキュメントでなければなりません。この場合、DOM を介してコンテンツを生成するのが最適です。応答を生成する際、修正しやすいという DOM ツリーの持つ柔軟性が役に立ちます。対応するサービスの Web 層で応答を生成することは良い方法です。Web 層で応答を生成することで、要求を処理するのに共通内部フォーマットを使用しながら応答をカスタマイズできます。これによって、ビジネスロジックの設計を簡略化して、コードの重複を防ぐことができます。Web 層で応答を生成することは、応答を組み立てる前に必要な情報すべてを収集することも可能にします。したがって、DOM ツリーをやりとりせずに済みます。さらに、Web 層で処理すれば、すべての応答に対して統一した変換方法を適用できるという利点もあります。このような統一した変換は、サーブレットフィルタ機構または JavaServer
Pages タグのいずれかの使用を介して可能です。
Web サービスにおける対話形式
ここまでは、Web サービス要求の処理と応答の生成について見てきました。次の問題点は、Web サービスプロバイダと Web サービス要求者間の対話をどのように設計するかということです。ここでは、この対話を設計する際に注意すべき点を示します。
まず注意すべき点は、メッセージの交換です。Simple Object Access Protocol (SOAP) は、XML ドキュメントを交換するための標準として一般的になりつつあります。SOAP は、IIOP と JRMP に準じた通信プロトコルです。これは、メッセージの転送に XML ベースのデータエンコーティング形式と HTTP/SMTP を使用するテキストベースのプロトコルです。SOAP は、使用されるプログラミング言語またはアプリケーションが実行されるプラットフォームには依存しません。これらの理由から、SOAP は Web サービスにおけるメッセージ交換に使用される標準として一般的になりつつあります。Java APIs for XML Messaging (JAXM) テクノロジは、SOAP によるメッセージングをサポートします。SOAP がメッセージ交換の標準として一般的になりつつある一方で、HTTP POST を使用して XML ドキュメントをやりとりすることも可能である点に注目する必要があります。
メッセージ交換の頻度を考慮した場合、少量の情報を含む多数のメッセージを交換することは明らかに非効率的です。SOAP メッセージを作成する際にオーバーヘッドがあることを、念頭に置かなければなりません。また、SOAP メッセージを送信する際もコストが生じます。したがって、少量の情報を何度もやりとりする (情報への粒度の細かいアクセス) 代わりに、情報交換をより包括的な方法で行う必要があります (情報への粒度の粗いアクセス)。粒度の細かいメッセージ交換は、パフォーマンスを低下させます。粒度の細かいメッセージ交換によって生じるもう 1 つの大きなコストは、ネットワーク遅延や帯域幅の問題に関する通信のコストです。また、このようなメッセージ交換は、Web サービスの設計をより難しいものにします。これは、エラーを処理する際に特別な注意を払う必要があるからです (情報に粒度の細かいアクセスをしている間に発生するエラーに対する処理やクリーンアップなど) 。すべての情報を要求の一部として送信して、すべての応答を 1 回で送信することで、設計をシンプルなものにし、エラー処理を簡単にし、パフォーマンスを向上させることができます。
次に注意すべき点は、結合のレベルです。これは、RPC とドキュメントベースのメッセージングの比較とも言えます。SOAP を介したドキュメントベースメッセージングを使用するのが好ましいでしょう。この方法では、XML ドキュメント (要求を含むドキュメント) は、SOAP メッセージのペイロードの一部として転送されます。受信側がペイロードを受け取り、XML ドキュメントを解析して、応答します。このようなメッセージ交換は、対話オブジェクトがリモートメソッドを知る必要がないため、結果として緩やかな結合となります。さらに、すべての関連データはドキュメントの一部として送信されるので、対話は自己完結型になります。
レガシーシステム統合用の Web サービス
ここまでは、既存のエンタープライズアプリケーションを使用しながら Web サービスを提供する方法に加えて、Web サービス要求の受信時と処理時に注意すべき点について見てきました。しかし、レガシーシステムにおける Web サービスの位置付けについては触れませんでした。ほとんどのレガシーシステムはオープンではありません。そこで、Web サービスとオープンなレガシーシステムの関係はどうなのかという問題が残ります。レガシーシステムに対しては、すでに多くの投資を行なっているので、この問題についてはしっかり解決しておく必要があります。
この問題を簡単に解消してくれるのが、J2EE プラットフォームです。J2EE プラットフォームのコネクタアーキテクチャは、レガシーシステムを J2EE アプリケーションに接続して使用することを可能にします。図 3は、レガシーシステム統合用に Web サービスを使用する場合のアーキテクチャの全体像を図示したものです。
J2EE コネクタアーキテクチャは、J2EE プラットフォームを異種エンタープライズ情報システム (EIS) に接続する際の標準アーキテクチャを定義します。EIS の例としては、ERP、メインフレームトランザクション処理、データベースシステム、およびJava プログラミング言語で書かれていないレガシーアプリケーションなどがあります。スケーラブルで、セキュリティ性が高く、かつトランザクション処理を行う一連の機構を定義することで、J2EE コネクタアーキテクチャは、アプリケーションサーバとエンタープライズアプリケーション間の EIS を統合することを可能にします。
したがって、図 3 に示すように、レガシーシステムは、 Web サービスとして利用できる J2EE プラットフォーム上で実行されるエンタープライズアプリケーションに接続できます。これによって、レガシーシステムを再定義せずに、J2EE を使用した市場投入を迅速に行うことが可能になります。また、レガシーシステムの厳格に統合されたトランザクション処理とセキュリティ機能の利点を利用することも可能になります。ビジネスロジックを考慮する必要があまりない場合は、コネクタを介して Web 層 (JSP/Servlets) または Java プログラムから直接レガシーシステムに接続することができます。
結論
この記事では、Web サービスにおける J2EE BluePrints プログラムと Web サービスの開発を可能にする J2EE プラットフォームの近日登場する機能に関する初期考察について説明しました。また、既存のエンタープライズ J2EE アプリケーションに加えてレガシーシステムを Web サービスの機能として利用する方法についても紹介しました。さらには、着信 Web サービス要求の処理と応答の生成に関する初期考察についても説明しました。今後、オープン XML 標準が成熟して、Web サービステクノロジの実際の実装が可能になるにしたがって、J2EE BluePrints プログラムは、開発者が既存のアプリケーションを「Web サービスを利用できるアプリケーション」にしたり、新たな Web サービスを開発することを可能にするサンプルアプリケーションと、ベストプラクティスガイドラインのリストを随時更新していきます。