ファイヤープロジェクト
SOAP Messaging(AXIS 1.2)
2005-10-12T23:00+09:00   matsu
今まで見てきた例は,SOAP RPCと呼ばれ,Webサービス呼び出しがコード上では単なるメソッド呼び出しに見えるものであった.今回はSOAP Messagingと呼ばれる,送受信XML電文をコード上でDOMのDocumentオブジェクトとして扱う例を見てみる.
SOAP RPCは,今までのサンプルで見てきたとおり,Webサービス呼び出しがコード上では単なるメソッド呼び出しに見えるものであった. SOAP RPCには以下のような特徴がある.
実装が直観的に分かりやすい
Webサービス呼び出しが単なるメソッド呼び出しに過ぎないように見えるので,実装者はそれがWebサービスかどうかといった点をほとんど意識しなくてすむ.
呼び出し構成の制限
その名の通りメソッド呼び出しであるので,基本的に同期呼び出しであり,キューイングはできない.
とにかく簡単手軽に実装できる半面,複雑なことはできないということである. これに対してSOAPエンジンからSOAP電文をまるごと受け取る方式がSOAP Messagingである. 特徴SOAP RPCの長所と短所が反転したようなイメージである.
SOAP MessagingによるWebサービスの実装では,以下の作業が必要である.
SOAPのメッセージボディの仕様の合意
SOAPのメッセージボディには,SOAPによらないサービス特有のXML文書が格納される. この仕様に対し,サービスのプロバイダとリクエスタで合意をとる必要がある.
サービスの実装
SOAP RPCでは,自由にメソッドを定義し呼び出すことができた. AXISのSOAP Messagingでは,呼び出されるメソッドのシグニチャは決まっているので,これを実装する必要がある. もちろん提供するサービス次第だが,このメソッドでは主にSOAP電文の解析とその結果に応じたビジネスロジックのディスパッチを行い,結果をSOAP電文にする処理を行う.
クライアントの実装
SOAP RPCの実装では,Callオブジェクトにサービスを特定するためのURLなどを記述し,Javaオブジェクトをパラメータとして渡せばよかった. SOAP Messagingでは,SOAP電文を生成してリクエスト,そしてレスポンスのSOAP電文を解析する処理が必要である.
このようにSOAP電文の解析がとにかく面倒臭そうだが,本頁ではSOAP MessagingによるWebサービスの最も簡単と思われるサンプルを作成した. すなわちSOAP電文の解析を行わず,とにかく固定の電文を送信し合うサンプルである. このサンプルを通してまずは全体の流れを掴んでみる.
以下にサンプルのサービスStaticResonceServiceを示す.
今回からjwsではなくJavaクラスとして実装するようにしてみた. SOAP Messagingのサービスはとくにこれといったインタフェースを実装する必要はないが,AXISによって呼び出される以下のようにDocumentオブジェクト一つを引数に持ち,Documentオブジェクトを返すメソッドを実装する必要がある.
Document doSubmission(Document input) throws AxisFault
inputが要求SOAP電文のボディ部のDOMツリー(org.w3c.dom.Document)である. 返り値は回答SOAP電文のボディ部のDOMツリーを返す. 今回のサンプルでは,これの解析は行わず,固定のXML電文を返している. 処理に失敗した場合は,AxisFaultをthrowする. SOAPにはサービス実装に失敗した際の電文仕様が定められており,AxisFautlをthrowするとAXISがこれを生成してクライアントに返してくれる. サービスを作成したら,デプロイする. deploy.wsddは以下.
要素serviceの属性providerがjava:RPCからjava:MSGに変わっていることに注意. AXISはここで,該当サービスがSOAP RPCかSOAP Messagingかを判定する.
以下にサンプルのクライアントStaticResponceSerivceClientを示す.
クライアントでは,要求SOAP電文のボディ部を
org.apache.axis.message.SOAPBodyElement
にて作成する. あとはSOAP RPCと同様にcall#invokeメソッドを呼び出す(ただしシグニチャは異なる). 返り値は回答SOAP電文のボディ部である. サンプルの実行結果を以下に示す.
$> java -jar axissample.jar http://localhost:8180/fireproject/services/StaticResponce
result = [<Responce from="StaticResponceService"/>]
matsu(C)
Since 2002
Mail to matsu