![]() |
Sun ONE Message Queue 開発者ガイド |
第 5 章 SOAP メッセージの操作
Sun ONE MQ では、SOAP ペイロードを含む JMS メッセージを送信できます。このため、高い信頼性で SOAP メッセージを転送できます。また、SOAP メッセージを JMS サブスクライバにパブリッシュすることもできます。この章では、次の手順を説明します。この章では、最初に SOAP 処理の概要を紹介し、添付ファイル付き SOAP メッセージ用の Java API (JAXM) について説明します。SOAP メッセージ処理を行うには、これらに関する知識が必要です。この章の最後の部分では、SOAP メッセージペイロードを含む JMS メッセージの作成方法について説明します。
SOAP 仕様について十分に理解している場合は、導入部分をとばして「Java での SOAP メッセージング」から読み始めてもかまいません。
SOAP とは
SOAP (Simple Object Access Protocol) は、分散環境内の複数のピア間で構造化データを交換するためのプロトコルです。交換されるデータの構造は、XML スキーマによって指定されます。SOAP メッセージは、データをシステムに依存しない移植可能な方法で表現できる XML 形式でコード化されているため、移植可能です。XML でコード化されたデータには、レガシーシステムからアクセスできます。また、複数の企業間で同じデータを共有することもできます。SOAP テクノロジは、XML によるデータの統合という特徴を活かして、Web サービスなどの Web ベースのコンピューティングでも一般的に使用されます。ファイアウォールは、SOAP パケットをそのコンテンツタイプ (text/xml-SOAP) に基づいて認識します。また、SOAP メッセージヘッダーに含まれる情報に基づいてメッセージをフィルタリングします。
SOAP 仕様には、XML メッセージ交換のための規則が記載されています。SOAP 仕様は、XML でコード化された情報を交換する必要がある Web サービスの基盤を形成します。通信を行う双方が、コード化された情報の交換に使用する固有のプロトコルを定義してもかまいません。しかし、SOAP のような標準を採用すれば、開発者は情報交換をサポートする汎用の部品を構築できます。こうした部品は、基本的な SOAP 交換に新たな機能を追加するソフトウェアであったり、SOAP メッセージングを管理するツールであったり、SOAP 処理をサポートするオペレーティングシステムの一部分であったりします。このサポートが得られれば、その他の開発者は Web サービスの作成作業に集中できます。
SOAP プロトコルについては、Web サイト http://www.w3.org/TR/SOAP にすべて説明されています。この節では、SOAP を使用する理由と JAXM API の操作をより簡単にする基本的概念の一部の説明だけを行います。
SOAP と Java for XML Messaging API
Java API for XML Messaging (JAXM) は、SOAP 標準に準拠させるための Java ベースの API です。この API で SOAP メッセージをアセンブルまたは逆アセンブルすると、構文的に正しい SOAP メッセージが構築されます。また、メッセージを次の送り先に転送する前にその部分部分を複数のアプリケーションで処理する必要がある場合、JAXM を使用することによってメッセージ処理を自動化できます。図 5-1 に、SOAP メッセージングの実装に使用される層を示します。この章では、SOAP と言語実装層に注目します。
図 5-1    SOAP メッセージング層
![]()
次の節では、先ほどの図に示した各層について詳しく説明します。この章の以降の部分では、SOAP と言語実装層に注目します。
トランスポート層
基礎となるメッセージングシステムは、回線上に送信されるメッセージの直列化と、送信先に着信したメッセージビットを解釈するトランスポートプロトコルまたはワイヤプロトコルです。SOAP メッセージの送信には、プロトコルをいくつ使ってもかまいません。しかし、SOAP 仕様に定義されているのは、HTTP とのバインディングだけです。SOAP は HTTP 要求/応答メッセージモデルを使用します。これにより、HTTP 要求内には SOAP 要求パラメータ、HTTP 応答内には SOAP 応答パラメータが設定されます。HTTP バインディングには、SOAP メッセージがファイアウォールを通過できるようにするという利点があります。
SOAP 層
トランスポート層の上には SOAP 層があります。この層は、SOAP 仕様書に定義されているとおり、メッセージの構成部分 (エンベロープ、ヘッダー、本体、添付ファイル) の識別に使用する XML スキームを指定します。添付ファイルを除く SOAP メッセージの部分とコンテンツは、すべて XML で書かれています。XML タグを使って SOAP タグを定義する方法については、次のサンプル SOAP メッセージを参照してください。
SOAP メッセージングを行うために実際に必要なのは、ワイヤトランスポート層と SOAP 層です。送信するメッセージを定義する XML ドキュメントの作成や、メッセージを一方から送信し、もう一方で受信するための HTTP コマンドの作成も可能です。この場合、クライアントは、指定された URL へ同期方式でメッセージを送信することしかできません。残念ながら、このようなメッセージングの有効範囲と信頼性はかなり制限されています。このような制限を克服するため、SOAP メッセージングには、プロバイダ層とプロファイル層が追加されています。
プロバイダ層
図 5-1 では、プロバイダ層を言語実装と配信セマンティクスの 2 つの機能部分として示しています。プロバイダ言語実装では、API 呼び出しを使って、SOAP に準拠した XML メッセージを作成できます。任意の JAXM が実装されていれば、Java クライアントは、SOAP メッセージとそのすべての部分を Java オブジェクトとして定義できます。クライアントは、JAXM を使ってコネクションを作成し、これを使ってメッセージを送信することもできます。同様に、Java で書かれた Web サービスも同じ (または別の) JAXM API 実装を使って、メッセージの受信、逆アセンブル、メッセージの受信の通知を行うことができます。
メッセージングのセマンティクス
SOAP プロバイダは、言語実装のほかに、メッセージ配信に関連するサービスを提供できます。たとえば、信頼性、持続性、セキュリティ、管理制御などのサービスがあります。MQ の将来のリリースでは、これらのサービスが SOAP メッセージング用として提供されます。
相互運用性
SOAP プロバイダは、SOAP 仕様に定義されているようにすべてのメッセージを構築または解体する必要があるため、SOAP を使用するクライアントとサービスには相互運用性があります。図 5-2 のように、SOAP メッセージングを行うクライアントとサービスは、同じ言語で書かれていなくてもかまいません。また、同じ SOAP プロバイダを使用していなくてもかまいません。標準化の必要があるのは、メッセージのパッケージのみです。
図 5-2    SOAP の相互運用性
![]()
JAXM クライアントまたはサービスを、異なるプロバイダを使用するサービスまたはクライアントと相互運用するには、双方が次の 2 点について合意する必要があります。
次の節で説明するように、プロファイルには追加の処理情報が含まれています。
プロファイル層
SOAP メッセージングの最後の層、プロファイル層は、SOAP プロバイダ で SOAP メッセージングを使用するビジネスパートナー間のメッセージングセマンティクスを管理します。プロファイルは「ebxml」のような業界標準であり、メッセージ処理の追加の規則を定義します。プロバイダは、メッセージファクトリがメッセージを作成するとき、メッセージのヘッダーにプロファイル情報を追加できます。SOAP メッセージヘッダーは SOAP メッセージングの主要な拡張手段です。ebxml プロファイルのサポートは、MQ の将来のリリースで追加される予定です。
SOAP メッセージ
SOAP メッセージング層の概略を把握したところで、今度は SOAP メッセージ自体に注目します。XML で記述された SOAP メッセージの描画は JAXM ライブラリによって行われます。しかし、正しい順序で JAXM 呼び出しを行うには、その構造を把握しておく必要があります。SOAP メッセージは、SOAP エンベロープ、オプションの SOAP ヘッダー、SOAP 本体からなる XML ドキュメントです。SOAP メッセージヘッダーには、1 つまたは複数の中間ノードを経て最終的な送信先までメッセージを配信するための情報が含まれています。
エンベロープは、メッセージを表す XML ドキュメントのルート要素です。これにより、メッセージが誰によってどのように処理されるかというフレームワークが定義されます。SOAP プロセッサは、エンベロープ要素を検出した時点で、その XML が SOAP メッセージであることを認識し、メッセージの各部分を検索できるようになります。
SOAP メッセージには添付ファイルが付属している場合もあります。添付ファイルは XML で記述されていなくてもかまいません。詳細は、次の「SOAP パッケージ化モデル」を参照してください。ヘッダーは、SOAP メッセージに機能を追加するための汎用メカニズムです。ヘッダーには、基本プロトコルの拡張機能を定義する子要素を含めることができます。子要素の数に制限はありません。たとえば、ヘッダーの子要素によって定義されるものとして、認証情報、トランザクション情報、ロケール情報などがあります。メッセージを処理するソフトウェアをアクターと呼びます。アクターは、ヘッダーのメカニズムを使って、ある機能が必須機能であるのかオプション機能であるのか、また誰によって使用されるのかを事前の合意なしで定義します。
SOAP メッセージは入れ子構造になっています。JAXM を使ってメッセージのアセンブルまたは逆アセンブルを行うとき、必要なメッセージ部分を取得するには、適切な順序で API 呼び出しを行う必要があります。たとえば、メッセージに新しいコンテンツを追加する場合、メッセージの本体部分を取得する必要があります。このためには、入れ子になった SOAP 部分、SOAP エンベロープ、SOAP 本体を使って、データの指定に使用する SOAP 本体要素を取得する必要があります。詳細は、「SOAP メッセージオブジェクト」を参照してください。
SOAP パッケージ化モデル
SOAP 仕様には、SOAP メッセージの 2 つのモデルが記述されています。1 つは完全に XML でエンコードされたモデルであり、1 つは XML 以外のデータの含む添付ファイルを送信元が追加できるようにするモデルです。次の 2 つの図を参照して、各モデルの SOAP メッセージの部分を確認してください。JAXM を使って SOAP メッセージとその部分を定義すると、この情報を理解しやすくなります。図 5-3 は、添付ファイルのない SOAP モデルを示します。このパッケージには、SOAP エンベロープ、ヘッダー、本体が含まれています。ヘッダーはオプションです。
図 5-3    添付ファイルのない SOAP メッセージ
![]()
JAXM を使って SOAP メッセージを構築するとき、どちらのモデルを採用するかを指定する必要はありません。添付ファイルを追加すると、図 5-4 のようなメッセージが構築されます。追加しない場合は、図 5-3 のようなメッセージが構築されます。
図 5-4 は、添付ファイル付きの SOAP メッセージを示します。添付ファイルの部分には、イメージファイル、プレーンテキストなどどのような種類のコンテンツでも含めることができます。メッセージの送信元は、添付ファイル付きの SOAP メッセージを作成するかどうかを指定できます。メッセージの受信先も、添付ファイルをコンシュームするかどうかを指定できます。
1 つまたは複数の添付ファイルを含むメッセージは、メッセージのすべての部分を含む MIME エンベロープに同封されます。JAXM では、クライアントが添付ファイル部分を作成すると、MIME エンベロープが自動的に生成されます。メッセージに添付ファイルを追加した場合、MIME ヘッダーに、その添付ファイル内のデータのタイプを指定する必要があります。
図 5-4    添付ファイル付き SOAP メッセージ
![]()
Java での SOAP メッセージング
SOAP 仕様には、プログラミングモデルや SOAP メッセージを構築するための API は定義されていません。SOAP メッセージのパッケージ化に使用できる XML スキーマが定義されているだけです。JAXM は、アプリケーションプログラミングインタフェースの 1 つです。JAXM を実装することにより、SOAP メッセージングのプログラミングモデルをサポートできます。また、SOAP メッセージの構築、送受信、確認のためにアプリケーションやツールの作成者が使用する Java オブジェクトを供給することができます。JAXM は、次の 2 つのパッケージを定義します。
javax.xml.soap: このパッケージのオブジェクトを使って、SOAP メッセージの各部分を定義したり、SOAP メッセージのアセンブルや逆アセンブルを行うことができます。プロバイダのサポートなしでも、このパッケージを使って SOAP メッセージを送信できます。
この章では、次の操作を行うために、javax.xml.soap パッケージとこれによって定義されているオブジェクトおよびメソッドの使用方法について説明します。javax.xml.messaging: このパッケージのオブジェクトでは、プロバイダを使って SOAP メッセージを送信したり、SOAP メッセージを受信したりできます。
また、JMS API と MQ を使って SOAP メッセージペイロードを伝送する JMS メッセージを送受信する方法についても説明します。
SOAP メッセージオブジェクト
図 5-5 に示すように、SOAP メッセージオブジェクトはオブジェクトツリーを形成します。javax.xml.soap パッケージには、ツリーオブジェクトの派生元となるクラスやインタフェースがすべて定義されています。
図 5-5    SOAP メッセージオブジェクト
![]()
上図に示されるように、SOAPMessage オブジェクトはSOAP 部分と添付ファイル部分の 2 つの部分に分けられるオブジェクトのコネクションです。重要なことは、添付ファイル部分に XML 以外のデータが含まれている可能性があることです。
メッセージの SOAP 部分のエンベロープには、本体 (データや障害情報を含む) とオプションのヘッダーが含まれています。JAXM を使って SOAP メッセージを作成すると、本体要素だけを作成する必要がある場合でも、SOAP 部分、エンベロープ、および本体が作成されます。このためには、本体要素の親、つまり SOAP 本体を取得する必要があります。
SOAPMessage ツリー内のオブジェクトに移動するには、次のコードに示されるように、ルートからツリー内を移動していく必要があります。たとえば、SOAPMessage MyMsg を作成したとします。この場合、次のような呼び出しで SOAP 本体を取得できます。
SOAPPart MyPart = MyMsg.getSOAPPart();
SOAPEnvelope MyEnv = MyPart.getEnvelope();
SOAPBody MyBody = envelope.getBody();
ここで、本体要素の名前を作成し (「ネームスペース」を参照)、SOAPMessage に本体要素を追加します。
たとえば、次のコードで本体要素の名前 (XML タグ表現) を作成します。
Name bodyName = envelope.createName("Temperature");
SOAPBodyElement myTemp = MyBody.addBodyElement(bodyName);
最後に、次のコードで本体要素 bodyName のデータを定義します。
継承されたメソッド
SOAP メッセージの要素はツリーを形成します。ツリー内の各ノードは Node インタフェースを実装します。エンベロープレベルから始まる各ノードは、さらに SOAPElement インタフェースも実装します。その結果、表 5-1 のような共有メソッドが得られます。
ネームスペース
XML ネームスペースでは、要素名や属性名を同じドキュメント内のその他の名前と区別できます。この節では、XML ネームスペースの概要と SOAP での使用方法を簡単に説明します。詳細は、 http://www.w3.org/TR/REC-xml-names/ を参照してください。明示的な XML のネームスペース宣言は、次の形式をとります。
この宣言は、prefix を特定の URI の別名として定義します。myElement 内で prefix と任意の要素または属性を使って、この要素名または属性名が URI で指定されたネームスペースに属するように指定できます。
xmlns: SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
この宣言は、ネームスペースの別名として SOAP_ENV を定義します。
http://schemas.xmlsoap.org/soap/envelope/
定義済みの別名は、Envelope 要素内の任意の属性または要素のプレフィックスとして使用できます。コード例 5-1 では、要素 <Envelope> と <Body> および属性 encodingStyle は、すべて URI "http://schemas.xmlsoap.org/soap/envelope/" で指定された SOAP ネームスペースに属します。
ネームスペースを定義する URI が実際の場所をポイントしている必要はありません。URI の目的は、属性名と要素名を区別することです。
事前定義済みの SOAP ネームスペース
SOAP には、次の 2 つのネームスペースが定義されています。JAXM を使ってメッセージを構築またはコンシュームする場合は、ネームスペースの設定および処理を正しく行い、不正なネームスペースを持つメッセージを破棄する必要があります。
ネームスペースによる SOAP 名の作成
SOAP メッセージの本体要素やヘッダー要素を作成するときは、Name オブジェクトを使って、その要素に適した名前を指定する必要があります。Name オブジェクトは、SOAPEnvelope.createName メソッドを呼び出すことで取得できます。このメソッドを呼び出すとき、パラメータとしてローカル名を指定するか、またはローカル名、プレフィックス、URI を指定できます。たとえば、次のコードは Name オブジェクト bodyName を定義します。
Name bodyName = MyEnvelope.createName("TradePrice",
"GetLTP",
"http://foo.eztrade.com");<GetLTP:TradePrice xmlns:GetLTP= "http://foo.eztrade.com">
次のコードでは、名前を作成し、SOAPBody 要素と関連付ける方法を示します。createName メソッドの使用方法と配置に注目してください。
SoapBody body = envelope.getBody(); //get body from envelope
Name bodyName = MyEnvelope.createName("TradePrice",
"http://foo.eztrade.com");SOAPBodyElement gltp = body.addBodyElement(bodyName);
Name オブジェクトのパース
特定の Name オブジェクトの名前をパースするときは、次の Name メソッドを使用して名前をパースします。
getQualifiedName は「prefix:LocalName」を返す。特定の名前を使用する場合、GetLTP:TradePrice を返す
送信先、メッセージファクトリ、コネクションオブジェクト
SOAP メッセージングは、メッセージファクトリによって作成された SOAP メッセージがコネクションを介してエンドポイントに送信されるとき行われます。
プロバイダを使用しない場合は、次の作業を行う必要があります。
次の 3 つの項では、エンドポイント、メッセージファクトリ、コネクションオブジェクトについて詳しく説明します。
SOAPConnectionFactory オブジェクトの作成
プロバイダを使用する場合は、次の作業を行う必要があります。メッセージの送信先を表す Endpoint オブジェクトの作成
MessageFactory オブジェクトの作成と、このオブジェクトによるメッセージの作成
エンドポイント
エンドポイントは、メッセージの最終的な送信先を表します。エンドポイントは、プロバイダを使用する場合 Endpoint クラス、使用しない場合 URLEndpoint クラスによって定義されます。
エンドポイントの構築
エンドポイントを初期化するときは、そのコンストラクタを呼び出すか、ネーミングサービス内でエンドポイントを検索します。エンドポイント用の管理対象オブジェクトの作成方法については、「JAXM 管理対象オブジェクトの使用」を参照してください。次のコードでは、コンストラクタを使って URLEndpoint を作成します。
myEndpoint = new URLEndpoint("http://somehost/myServlet");
エンドポイントによるメッセージのアドレス指定
プロバイダを使用する場合、メッセージを作成するメッセージファクトリにより、メッセージヘッダー内にエンドポイントが指定されます。プロバイダを使用しない場合、SOAP メッセージの送信に使用する SOAPConnection.call メソッドのパラメータとしてエンドポイントを指定できます。
複数のエンドポイントへのメッセージ送信
管理対象オブジェクトを使ってエンドポイントを定義する場合は、その管理対象オブジェクトと複数の URL を関連付けることができます。この場合、各 URL が着信 SOAP メッセージを処理することができます。次のサンプルコードは、検索名が myEndpoint というエンドポイントと 2 つの URL (http://www.myServlet1/ および http://www.myServlet2/) を関連付けています。
imqobjmgr add -t e -l "cn=myEndpoint" -o "imqSOAPEndpointList=http://www.myServlet1/
http://www.myServlet2/"この構文により、SOAP コネクションを使って複数のエンドポイントに SOAP メッセージをパブリッシュできます。エンドポイント管理対象オブジェクトの詳細は、「JAXM 管理対象オブジェクトの使用」を参照してください。
メッセージファクトリ
メッセージファクトリを使って SOAP メッセージを作成できます。
プロバイダを使用する場合は、プロバイダコネクションの createMessageFactory メソッドを使ってメッセージファクトリを作成します。たとえば、プロバイダコネクションが con の場合、次のコードでメッセージファクトリ mf を作成できます。
プロバイダを使用しない場合は、次のようにメッセージファクトリを直接インスタンス化します。
- MessageFactory mf = con.createMessageFactory(xProfile);
- createMessageFactory メソッドに profile パラメータを指定することにより、メッセージファクトリによって作成されたメッセージのヘッダーに配置するアドレス指定やその他の情報を決定します。
コネクション
JAXM を使って SOAP メッセージを送信する場合は、SOAPConnection または ProviderConnection を取得する必要があります。さらに、MQ を使って SOAP メッセージを転送することもできます。詳細は、「SOAP と MQ の統合」を参照してください。
SOAP コネクション
SOAPConnection では、リモートロケーションにメッセージを直接送信できます。SOAPConnection オブジェクトを取得するには、単に静的メソッド SOAPConnectionFactory.newInstance() を呼び出します。このタイプのコネクションでは、信頼性も安全性も保証されません。
プロバイダコネクション
ProviderConnectionFactory から取得した ProviderConnection を使って、特定のメッセージングプロバイダへのコネクションを作成します。プロバイダを使って SOAP メッセージを送信する場合、このメッセージはプロバイダに転送されます。このメッセージは、プロバイダによって最終的な送信先に配信されます。プロバイダは信頼性の高い、安全なメッセージングを保証します。現在、MQ は SOAP プロバイダサポートを提供していません。
JAXM 管理対象オブジェクトの使用
管理対象オブジェクトは、プロバイダ固有の設定およびネーミング情報をカプセル化するオブジェクトです。エンドポイントオブジェクトの場合、このようなオブジェクトをインスタンス化するか、管理対象オブジェクトを作成してエンドポイントオブジェクトのインスタンスに関連付けることができます。JNDI 検索でエンドポイントを作成する方法には、コードからエンドポイントの URL を切り離すことができるという利点があります。この場合、アプリケーションは、コードの再コンパイルなしで送信先を変更できます。さらに、プロバイダへの非依存性という利点も得られます。
SOAP 要素の管理対象オブジェクトの作成方法は、MQ 内で管理対象オブジェクトを作成する方法と同じです。具体的には、オブジェクトマネージャ (imqobjmgr) ユーティリティを使ってオブジェクトの検索名、属性、タイプを指定します。
エンドポイント管理対象オブジェクトの作成時に指定する必要がある属性やその他の情報は、表 5-2 のとおりです。すべての属性を文字列として指定してください。
コード例 5-2 では、imqobjmgr コマンドを使ってエンドポイントの管理対象オブジェクトを作成し、オブジェクトストアに追加する方法を示します。-i オプションで、オブジェクトストア属性 (-j オプション) を定義する入力ファイル名を指定します。
管理対象オブジェクトを作成してオブジェクトストアに追加しておけば、JAXM アプリケーション内でエンドポイントを使用するとき、この管理対象オブジェクトを使用できます。コード例 5-3 では、JNDI 検索の初期コンテキストを作成してから、必要なオブジェクトを検索します。
管理対象オブジェクトの一覧表示、削除、更新も可能です。詳細は、『MQ 管理者ガイド』を参照してください。
SOAP メッセージングモデルと例
この節では、JAXM を使って SOAP メッセージを送受信する方法を説明します。JAXM を使って SOAP メッセージを構築し、JMS メッセージのペイロードとして送信することもできます。詳細は、「SOAP と MQ の統合」を参照してください。JAXM は、SOAP メッセージングの実行に使用できる 2 つのモデルを提供します。1 つは SOAPConnection オブジェクトを使用し、1 つは ProviderConnection オブジェクトを使用します。現在、MQ は ProviderConnection オブジェクトをサポートしていません。
SOAP メッセージングプログラミングモデル
この項では、JAXM を使った SOAP メッセージングで使用するプログラミングモデルの概要を説明します。SOAP メッセージは、コネクションを経由してエンドポイントへ送信されます。コネクションには、ポイントツーポイントコネクション (SOAPConnection クラスによって実装される) とプロバイダコネクション (ProviderConnection クラスによって実装される) の 2 種類があります。
ポイントツーポイントコネクション
ポイントツーポイントコネクションを使って、要求 - 応答メッセージングモデルを確立します。要求 - 応答モデルは 図 5-6 に示すとおりです。
図 5-6    要求 - 応答メッセージング
![]()
エンドポイントを作成して、メッセージを送信する SOAPConnection.call メソッドに渡される URL を指定する
クライアントは、呼び出しメソッドから返される SOAPMessage オブジェクトを無視します。このオブジェクトはクライアントのブロックを解除するために返されるだけです。
SOAPConnection ファクトリを作成し、SOAP コネクションを取得する
- エンドポイントのさまざまな作成方法については、「エンドポイント」を参照
メッセージファクトリを作成し、これを使って SOAP メッセージを作成する
要求- 応答メッセージを待機する JAXM サービスは ReqRespListener オブジェクトを使ってメッセージを受信します。
ポイントツーポイントメッセージングを行うクライアントの詳しい例については、「SOAP クライアントの作成」を参照してください。
プロバイダコネクション
プロバイダコネクションを使って、単方向メッセージングを実装できます。単方向メッセージングモデルの仕組みは 図 5-7 に示すとおりです。
図 5-7    単方向メッセージング
![]()
ポイントツーポイントモデルとは対照的に、メッセージの最終的な送信先はプロバイダによってメッセージヘッダー内に記述されます。(管理者がメッセージングプロバイダを構成する場合は、Endpoint オブジェクトのリストを提供できます。クライアントがプロバイダを使ってメッセージを送信する場合は、プロバイダはメッセージングプロバイダの Endpoint オブジェクトに記載された送信先に対してのみメッセージを送信します。)
プロバイダコネクション経由で送信されるメッセージは、常にプロバイダ内の中間送信先を経て最終的な送信先に転送されます。プロバイダは、転送の信頼性とメッセージの機密性に対しても責任を負います。
単方向メッセージを待機する JAXM サービスは、OnewayListener オブジェクトを使って非同期方式でメッセージを受信します。
添付ファイルの操作
メッセージに XML 以外のデータを含める場合は、添付ファイルとして追加する必要があります。1 つのメッセージに任意の数の添付ファイル部分を追加できます。添付ファイル部分の内容は、プレーンテキストからイメージファイルまで多岐にわたります。添付ファイルを作成するには、URL オブジェクトを作成して、SOAP メッセージに添付するファイルの場所を指定します。さらに、添付ファイル内のデータを解釈するためのデータハンドラを作成します。最後に、添付ファイルを SOAP メッセージに追加します。
添付ファイル部分を作成し、メッセージに追加するには、JavaBeans Activation Framework (JAF) API を使用する必要があります。この API では、データの任意の部分のタイプを判断し、そのアクセスをカプセル化できます。また、使用可能な操作を検出して、この操作を実行する Beans をアクティブ化することもできます。JavaBeans Activation Framework を使用するためには、クライアントコードに activation.jar ライブラリを追加する必要があります。
URL オブジェクトを作成し、初期化して、SOAP メッセージに添付するファイルの場所を追加します。
添付ファイルを作成し、メッセージに追加したあとは、通常どおりメッセージを送信できます。データハンドラを作成し、デフォルトハンドラで初期化して、ハンドラのデータソースの場所を表す URL を渡します。
添付ファイル部分を作成し、イメージの URL を含むデータハンドラで初期化します。
添付ファイル部分を SOAP メッセージに追加します。
JMS を使ってメッセージを送信する場合は、SOAPMessageIntoJMSMessage 変換ユーティリティを使って、添付ファイル付きの SOAP メッセージを JMS メッセージに変換できます。その後、MQ を使って、このメッセージをトピックの JMS キューに送信できます。
例外および障害処理
SOAP アプリケーションは、SOAP 例外と SOAP 障害の 2 種類のエラー報告メカニズムを使用できます。
SOAP 例外では、SOAP 要求の生成時や応答の非整列化時にクライアントサイドで発生したエラーを処理できます。
SOAP 障害では、要求の非整列化時、メッセージの処理時、応答の整列化時にサーバサイドで発生したエラーを処理できます。こうしたエラーに対して、サーバサイドのコードは、本体要素ではなく障害要素を含む SOAP メッセージを作成し、このメッセージをその送信元へ送信する必要があります。メッセージの受信側がメッセージの最終的な送信先ではない場合は、受信側自体を soapactor として特定し、メッセージの送信側がエラーの発生場所を特定できるようにします。詳細は、「SOAP 障害の処理」を参照してください。
SOAP クライアントの作成
ポイントツーポイントメッセージングの SOAP クライアントを作成するには、次の手順に従って呼び出しを行います。
SOAPConnectionFactory のインスタンスを取得します。
SOAPConnectionFactory myFct = SOAPConnectionFactory.newInstance();
SOAPConnectionFactory オブジェクトから SOAP コネクションを取得します。
メッセージの作成に使用する MessageFactory オブジェクトを取得します。
メッセージファクトリを使ってメッセージを作成します。
ここで myEnvp オブジェクトから本体要素を取得できます。
- SOAPMessage message = myMsgFct.createMessage();
- 作成されたメッセージには、次の図に示す部分がすべて含まれます。
- この時点では、メッセージのコンテンツはありません。コンテンツを追加するには、SOAP 本体要素を作成し、その名前とコンテンツを定義して、SOAP 本体に追加する必要があります。
- メッセージの各部分にアクセスするには、親要素上で get メソッドを呼び出して子要素を取得することにより、ツリー内を移動する必要があります。たとえば、SOAP 本体に移動するには、SOAP 部分と SOAP エンベロープを取得することから開始します。
- SOAPPart mySPart = message.getSOAPPart();
- SOAPEnvelope myEnvp = mySPart.getEnvelope();
SOAP 本体 (またはヘッダー) に要素を追加するときは、まず envelope.createName メソッドを呼び出し、その要素の名前を作成します。このメソッドが返す Name オブジェクトを、本体要素 (またはヘッダー要素) を作成するメソッドにパラメータとして渡します。
ここで、gltp 要素に追加するもう一つの本体要素を作成します。
- Name bodyName = envelope.createName("GetLastTradePrice", "m",
"http://eztrade.com")
- SOAPBodyElement gltp = body.addBodyElement(bodyName);
これで、本体要素 mySymbol のデータを定義できるようになります。
- Name myContent = envelope.createName("symbol");
- SOAPElement mySymbol = gltp.addChildElement(myContent);
メッセージを送信したり、メッセージに書き込みを加えたりするたびに、その内容が自動保存されます。ただし、受信済みのメッセージや送信済みのメッセージに変更を加えた場合は、その内容をすべて保存して、手作業でメッセージを更新する必要があります。たとえば、次のように指定します。
- mySymbol.addTextNode("SUNW");
- 生成される SOAP メッセージオブジェクトは、次の XML スキーマと同等になります。
メッセージを送信する前に、送信先エンドポイントの URL を持つ URLEndpoint オブジェクトを作成する必要があります。ただし、メッセージヘッダーにアドレス指定情報を追加するようなプロファイルを使用する場合、この処理は不要です。
ここで、メッセージを送信できます。
最後に、不要な SOAPConnection オブジェクトを終了します。
SOAP サービスの作成
SOAP サービスは、SOAP メッセージの最終的な送信先になります。現時点では、サーブレットとして実装する必要があります。独自のサーブレットを作成できますが、必要に応じて、soap.messaging パッケージ内に提供される JAXMServlet クラスを拡張することもできます。この項では、JAXMServlet クラスを使って SOAP サービスを作成する方法を説明します。サーブレットは、ReqRespListener インタフェースか OneWayListener インタフェースを実装する必要があります。ReqRespListener が応答を要求するという点を除けば、2 つのインタフェースは同じです。
どちらのインタフェースを使用する場合でも、onMessage(SOAPMsg) メソッドを実装する必要があります。JAXMservlet は、HTTP POST メソッドでメッセージを受信したあと、onMessage を呼び出します。この場合、着信メッセージを SOAP メッセージに変換する doPost() メソッドを実装する必要はありません。
コード例 5-4 は、JAXM サーブレットユーティリティクラスを使用する SOAP サービスの基本構造です。
コード例 5-4    メッセージコンシューマのスケルトン public class MyServlet extends JAXMServlet implements
ReqRespListener{ public SOAPMessage onMessage(SOAP Message msg) { // 処理メッセージ } コード例 5-5 は、簡単な ping メッセージサービスの例です。
コード例 5-5    簡単な ping メッセージサービス public class SOAPEchoServlet extends JAXMServlet
implements ReqRespListener{public SOAPMessage onMessage(SOAPMessage mySoapMessage) { return mySoapMessage } } 表 5-3 では、JAXM サーブレットが使用するメソッドについて説明します。独自のサーブレットを作成する場合は、同様の処理を行うメソッドを用意する必要があります。JAXMServlet を拡張する場合は、Init メソッドと SetMessageFactory メソッドをオーバーライドして、onMessage メソッドを実装しなければなりません。
メッセージの逆アセンブル
onMessage メソッドは、サーブレットから受け取った SOAP メッセージを逆アセンブルし、そのコンテンツを正しく処理する必要があります。メッセージの処理中に問題が発生した場合、サービスは、SOAP 障害オブジェクトを作成し、クライアントに送信する必要があります (詳細は、「SOAP 障害の処理」を参照)。SOAP メッセージ処理では、本体要素の場所を特定してそのコンテンツを処理するとともに、ヘッダーも操作する必要があります。次のサンプルコードでは、onMessage メソッドの本体に含まれる SOAP メッセージを逆アセンブルします。基本的に、SOAP メッセージの解析には、Document Object Model (DOM) API を使用する必要があります。
DOM API の詳細は、http://xml.coverpages.org/dom.html を参照してください。
添付ファイルの処理
SOAP メッセージには、添付ファイルを付けることができます。添付ファイルの作成および追加方法を示すサンプルコードについては、コード例 5-7 を参照してください。添付ファイルの受信および処理方法を示すサンプルコードについては、コード例 5-8 を参照してください。添付ファイルの処理には、Java Activation Framework API を使用する必要があります。詳細は、http://java.sun.com/products/javabeans/glasgow/jaf.html を参照してください。
メッセージへの応答
メッセージに応答するときは、サーバサイドでクライアントの役割をします。
SOAP 障害の処理
サーバサイドコードは、SOAP 障害オブジェクトを使って、要求の非整列化時、メッセージの処理時、応答の整列化時にサーバサイドで発生したエラーを処理する必要があります。SOAPFault インタフェースは SOAPBodyElement インタフェースを拡張します。SOAP メッセージは、サーバサイド上でエラー報告を行う特殊な要素および形式を備えています。要求処理時に発生したエラーを報告するため、SOAP メッセージ本体に SOAP 障害要素が含まれることがあります。SOAPFault オブジェクトを含む SOAP メッセージは、サーバサイドで作成され、サーバからクライアントに返されます。この SOAP メッセージは、メッセージの送信元に対して、予想外の動作をすべて報告します。
図 5-8 に示されるように、SOAP 障害オブジェクトは、SOAP 本体の子オブジェクトとして、SOAP メッセージオブジェクトに含まれています。詳細オブジェクトおよび詳細エントリオブジェクトは、受信済みのメッセージの本体の形式が不正である場合と、受信済みのメッセージの本体に不適切なデータが含まれている場合以外は不要です。この場合、詳細エントリオブジェクトは、不正な形式のデータを説明するために使用されます。
図 5-8    SOAP 障害要素
![]()
faultcode
faultstring
- エラーを識別するコード (修飾名)。ソフトウェアは、このコードを使って、障害を検出するアルゴリズム的メカニズムを提供します。事前定義済みの障害コードは、表 5-4 のとおりです。この要素は必須要素です。
faultactor
detail
- 障害のソースを指定する URI。メッセージのパス間で障害の原因となったアクター。メッセージが中間ノードを経由せずに最終的な送信先に送信される場合、この要素は不要です。中間ノードで障害が発生した場合、その障害には faultactor 要素が含まれることになります。
事前定義済みの障害コード
SOAP 仕様には、4 つの事前定義済み faultcode 値が規定されています。これらのネームスペース識別子は、http://schemas.xmlsoap.org/soap/envelope/ です。
これらの標準障害コードは、障害のクラスを表します。これらのコードは、末尾にピリオドと名前を追加することで拡張できます。たとえば、Server.OutOfMemory コード、Server.Down コードなどと定義できます。
SOAP 障害の定義
JAXM では、SOAPFault オブジェクトのメソッドを使って、faultcode、faultstring、faultactor の値を指定できます。次のコードでは、SOAP 障害オブジェクトを作成し、faultcode、faultstring、faultactor の各属性を設定します。
サーバは、サーバエラーが発生した場合、着信 SOAP メッセージへの応答としてこのオブジェクトを返すことができます。
次のサンプルコードは、詳細および詳細エントリオブジェクトを定義する方法を示します。詳細エントリオブジェクトの名前を作成する必要があります。
SOAP と MQ の統合
この節では、SOAP ペイロードを含む JMS メッセージの送受信および処理方法を説明します。MQ には、JMS API を使って SOAP メッセージを送受信するときに役立つユーティリティが付属しています。このユーティリティでは、MQ の高信頼メッセージングサービスを活用するため、SOAP メッセージを JMS メッセージに変換することができます。さらに、受信側では、JMS メッセージを SOAP メッセージに変換し直し、JAXM API を使って処理することができます。
SOAP ペイロードを含む JMS メッセージを送受信または処理するには、次の処理を行います。
com.sun.messaging.xml.MessageTransformer ライブラリをインポートします。このユーティリティのメソッドを使って、SOAP メッセージと JMS メッセージ間の変換を行います。
次に、このプロセスを表す使用例とサンプルコードの例をいくつか紹介します。SOAP メッセージを転送する前に、MessageTransformer.SOAPMessageIntoJMSMessage メソッドを呼び出す必要があります。このメソッドは SOAP メッセージを JMS メッセージに変換します。変換後の JMS メッセージを通常の JMS メッセージと同様に送信します。プログラムの簡便化のため、SOAP メッセージの受信専用の送信先を選択しておくことをお勧めします。つまり、SOAP メッセージの送信先となる特定のキューまたはトピックを作成し、この送信先には SOAP メッセージだけを送信するようにします。
受信側では、通常の JMS メッセージの場合と同様にして、SOAP ペイロードを含む JMS メッセージを取得します。その後、MessageTransformer.SOAPMessageFromJMSMessage ユーティリティを使用して SOAP メッセージを抽出し、JAXM を使って SOAP メッセージを逆アセンブルしたあと、その他の処理を行います。たとえば、SOAPMessage を取得する場合は、次のような呼び出しを行います。
- SOAP メッセージを JMS メッセージに変換するときは、次のような呼び出しを行う必要があります。
- Message myMsg= MessageTransformer.SOAPMessageIntoJMSMessage
(SOAPMessage, Session);
- Session 引数は、Message をプロデユースする時に使用するセッションを指定します。
例 1 : SOAP 処理の延期
最初の例 (図 5-9) では、着信 SOAP メッセージはサーブレットによって受信されます。SOAP メッセージを受信したサーブレット MyServlet は、MessageTransformer ユーティリティを使って、このメッセージを JMS メッセージに変換し、高い信頼性でアプリケーションに転送します。このアプリケーションは、受信した JMS メッセージを SOAP メッセージに再変換し、SOAP メッセージのコンテンツを処理します。サーブレットが SOAP メッセージを受信する仕組みについては、「SOAP サービスの作成」を参照してください。
図 5-9    SOAP 処理の延期
![]()
SOAP メッセージを JMS メッセージに変換して、JMS メッセージを送信するには
ConnectionFactory オブジェクトをインスタンス化し、その属性を設定します。次に例を示します。
ConnectionFactory オブジェクトを使って Connection オブジェクトを作成します。
Connection オブジェクトを使って Session オブジェクトを作成します。
MQ メッセージサービス内の物理的な送信先に対応する MQ Destination 管理対象オブジェクトをインスタンス化します。この例の場合、管理対象オブジェクトは mySOAPQueue、このオブジェクトが参照する物理的な送信先は myPSOAPQ です。
MessageTransformer ユーティリティを使って SOAP メッセージを JMS メッセージに変換します。なお、ここでは、MySOAPMsg という名前の SOAP メッセージを使用するものとします。
QueueSender メッセージプロデューサを作成します。
キューへメッセージを送信します。
- このメッセージプロデューサは mySOAPQueue に関連付けられており、キュー送信先 myPSOAPQ にメッセージを送信する際使用されます。
- QueueSender myQueueSender = myQSess.createSender(mySOAPQueue);
受信した JMS メッセージを SOAP メッセージに変換して処理するには
ConnectionFactory オブジェクトをインスタンス化し、その属性値を設定します。
ConnectionFactory オブジェクトを使って Connection オブジェクトを作成します。
Connection オブジェクトを使って 1 つまたは複数の Session オブジェクトを作成します。
Destination オブジェクトをインスタンス化し、その名前属性を設定します。
Session オブジェクトと Destination オブジェクトを使って、必要な MessageConsumer オブジェクトを作成します。
必要に応じて、MessageListener オブジェクトをインスタンス化し、MessageConsumer オブジェクトに登録します。
手順 2 で作成した QueueConnection を起動します。クライアントによるコンシュームのためのメッセージは、確立されているコネクションを必ず経由して配信されます。
キューからメッセージを受信します。
Message Transformer を使って JMS メッセージを SOAP メッセージに再変換します。
将来の処理に備えて、SOAP メッセージを逆アセンブルします。詳細は、「SOAP メッセージオブジェクト」を参照してください。
- SOAPMessage MySoap =
MessageTransformer.SOAPMessageFromJMSMessage
(myJMS, MyMsgFactory);
- MessageFactory 引数に NULL を指定した場合、デフォルトのメッセージファクトリを使って SOAP メッセージが構築されます。
例 2 : SOAP メッセージのパブリッシュ
次の例 (図 5-10) では、着信 SOAP メッセージはサーブレットによって受信されます。サーブレットは、SOAP メッセージを JMS メッセージとしてパッケージ化し、トピックに転送 (高信頼) します。このトピックに加入している各アプリケーションは、JMS メッセージを受信し、SOAP メッセージに再変換して、そのコンテンツを処理します。
図 5-10    SOAP メッセージのパブリッシュ
![]()
JMS メッセージをキューではなくトピックに送信する点を除けば、この処理は、前の例とまったく同じ方法で行われます。コード例 5-7 に、MQ を使って SOAP メッセージをパブリッシュする例を示します。
サンプルコード
この項では、2 つのサンプルコードを取り上げて説明します。最初に取り上げるのは、SOAP ペイロードを含む JMS メッセージを送信する例です。次に取り上げるのは、JMS/SOAP メッセージを受信し、SOAP メッセージを処理する例です。コード例 5-7 では、JMS API、JAXM API、JAF API を使って、添付ファイル付きの SOAP メッセージを JMS メッセージのペイロードとして送信します。SendSOAPMessageWithJMS のコードには、次のメソッドが含まれています。
init メソッドを呼び出して、メッセージのパブリッシュに必要なすべての JMS オブジェクトを初期化するコンストラクタ
コード例 5-8 では、JMS API、JAXM API、DOM API を使って、添付ファイル付きの SOAP メッセージを JMS メッセージのペイロードとして受信します。ReceiveSOAPMessageWithJMS のコードには、次のメソッドが含まれています。SOAP メッセージと添付ファイルを作成し、SOAP メッセージを JMS メッセージに変換して、この JMS メッセージをパブリッシュする send メソッド
send メソッドと close メソッドを呼び出す main メソッド
init メソッドを呼び出して、メッセージの受信に必要なすべての JMS オブジェクトを初期化するコンストラクタ
メッセージを配信し、リスナーに呼び出される onMessage メソッド。onMessage メソッドは、Message Transformer ユーティリティを使用し JMS メッセージを SOAP メッセージに変換し、JAXM API を使って SOAP 本体を処理し、JAXM および DOM API を使ってメッセージの添付ファイルを処理する
ReceiveSOAPMessageWithJMS クラスを初期化する main メソッド
前へ 目次 索引 次へ
Copyright © 2002 Sun Microsystems, Inc. All rights reserved.
最終更新日 2002 年 6 月 19 日