連載
» 2001年03月02日 00時00分 公開

SOAPの仕掛け(1):SOAPの仕掛けはどうなっている? (2/3)

[米持幸寿,日本アイ・ビー・エム株式会社]

SOAP V1.1に規定されていること

SOAPメッセージの構造

 SOAPで規定しているのは、郵便でいうところの封筒の仕様である。封筒には、あて名を書きなさい、送り主を書きなさい、中身を入れなさい、といった具合である。SOAPメッセージは、次のような構造をしている(図1)。

図1 SOAPメッセージの構造 図1 SOAPメッセージの構造

 実は、この中身に関してはまだあまり議論がされていないといっていいだろう。とりあえず封筒だけでもきちんと決めて、郵便が届くようにしよう、ということなのである。

 図1中のカッコ( )内は、実際にSOAPメッセージがXML文書として作成されるときのタグ名であり、名前空間を使っている。当然ながら、SOAPの実装をするときには、XMLプロセッサは名前空間をサポートしている必要がある。

 Envelope要素の中には、HeaderとBodyの2つの要素のみが入れられる。Headerはオプションであり、必要に応じて入れる。Bodyは必ず1つだけ入れなければならない。

宛先情報を付加するSOAPエンベロープ

 SOAPエンベロープは、SOAPメッセージの一番外側の要素となる。名前空間として「XML Schema for SOAP v 1.1 Envelopehttp://schemas.xmlsoap.org/soap/envelope/)」を使う。次の属性を持っている。

encodingStyle属性
 直列化の方式を指定する。直列化とは、例えば、Javaのint変数に入っている値を、どのようにして文字列に変換するか、ということである。SOAP仕様ではSOAPエンコーディングというのを規定しているが、その場合は、「XML Schema for SOAP v 1.1 Encodinghttp://schemas.xmlsoap.org/soap/encoding/)」を指定することになる。

 ちなみに、この属性はほかの要素に指定することもできる。その場合には、指定した要素とその子どもにそれがあてはめられることになる。

 ここに規定されていない(別の名前空間に規定されている)属性を指定することもできるが、その場合は名前空間の修飾を明示する必要がある。同様に、Envelope要素の下に、Header、およびBody以外の要素を置く場合にも、名前空間の修飾をする必要がある。

メッセージングの機構を実現するSOAPヘッダ

 SOAPエンベロープの子どもとしてオプションで入れることのできる要素で、メッセージの受信者(処理する人)に対して、どう扱うべきか、ということを知らせるために使う。どう扱うべきか、というのは、次の属性によって表現することになる。

actor属性
 このメッセージを最終的に受け取って処理するサーバのURI(つまり、これが本当のあて先)を指定する。こうすることによって、メッセージングの機構を実現する。

mustUnderstand属性
 XMLでは「知らないタグを読み飛ばす」ということがしばしば行われるが、mustUnderstand属性が指定されている要素に関しては、それが許されないことになっている。もし、mustUnderstand="1"と指定されている要素が、あて先によって理解できない場合には、MustUnderstandというエラーを返さなければならない。無視はいけないよ、という意味である。

XML文書で構成されるSOAPボディ

 封筒の中身に関しては、基本的に規定はない。自由にXML文書をこの中に含めることができる。ただし、SOAPメッセージの処理においてエラーが発生したときには、このBody要素の中にFaultという要素を入れてレスポンスを送り返すことが決められている。また、RPCとして使う場合には、あとに基本的な規定がされている。

エラー記述のためのSOAP Fault

 SOAP Faultは、SOAPメッセージの取り扱い中に発生したエラーを記述するためのSOAPメッセージである。これは、メッセージを受け取った人が作るものとそうでないものとがある。SOAP Faultの構造は以下のようになる。

  • SOAP Fault
    • faultcode:次の値のどれか
      • VersionMismatch:エンベロープの名前空間の不一致
      • MustUnderstand:mustUnderstandの付いたHeader要素が理解できない
      • Client:送られてきたメッセージの構成がおかしい
      • Server:サーバー側のエラー(通信など)
    • faultstring:人間が読むためのエラーメッセージ
    • faultactor:このエラーを作ったサーバーのURI
    • detail:詳細の記述

以上の内容を図示すると、次のようになる(図2、図3)。まず、うまく交換ができた場合には、図2のようになる。

図2 SOAPメッセージの交換に成功した場合 図2 SOAPメッセージの交換に成功した場合

 失敗した場合には、図3のようになる。

図3 SOAPメッセージの交換に失敗した場合 図3 SOAPメッセージの交換に失敗した場合

SOAP符号化

 SOAP符号化(SOAPエンコーディング)は、SOAPを使ってメソッドの引数や戻り値を搬送するために、さまざまな型のデータをXML文書に変換して元に戻すためのルールを規定している。しかし、実のところ、これらのルールは、XML Schemaに規定されている内容をそのまま採用しており、その名前空間を使うことになる。規定されているのは次の型である。

  • 単純型
    • XML Schema Part 2 : Datatypesに規定されているすべての型
    • 文字列
    • 列挙
    • バイト配列
  • 多態的アクセサ
  • 複合型
    • 複合値、構造体と値参照
    • 配列
      • 部分的に転送される配列
      • 疎な配列
    • 一般的な複合

 詳細は仕様を読んでいただくことにするが、これらのルールに準拠することによりSOAP同士で正しく会話が成り立つはずである。

HTTP-SOAP

 SOAPは、トランスポートに何を使うかを規定していない。つまり、何を使っても構わない。郵便の封筒を運ぶとき、郵便局の人が大きな袋に入れようが、箱に入れようが、車で運ぼうが、バイクで運ぼうが構わないということである(ただし、SOAPメッセージは同時に複数のものを送ることにはなっていない)。

 しかし、HTTPを使ってSOAPの交換を行う例に関しては、Noteの中で規定している。

 HTTPをトランスポートとして使う場合、HTTPSのように暗号化して使うことが一般的に考えられる。しかし、ファイアウォールやプロキシサーバにまったく情報が読めないと困ることから、目的のURIのみ、ヘッダ部分に書き込むことができることになっている。SOAPActionというヘッダにこれを指定することになる。これは、リクエストにのみ必要である。

 また、エラーが発生したときにはHTTPコードの500を返し、レスポンスとしてSOAP FaultをBodyに含んだSOAPメッセージを返すことが決められている。

SOAPによるRPC

 SOAPでRPC(Remote Procedure Call)を行う場合の構造化の形式についていくつか規定していることがある。まず、RPCを行うために必要な情報は

  • 対象オブジェクトのURI
  • メソッド名
  • 選択可能なメソッドシグニチャ
  • メソッドに対するパラメータ
  • 選択可能なヘッダデータ

である。そして、Bodyに入れるRPCのメソッドのデータをどうするかを決めている。

  • リクエスト
    • 構造体にする
    • メソッド名と同じ名前と型を付ける
    • パラメータも同じ名前と型を付け、メソッドの形式と同じ順序で出現すること
  • メソッドの戻り値
    • 構造体にする
    • 名前は重要でないが、慣例的に「メソッド名Response」とする
  • メソッド違反
    • SOAP Fault要素に従う

以上が、SOAPによって規定されている内容である。

 SOAPに規定されていることを理解する必要があるのは、SOAPのランタイムを実装する技術者だけだろう。SOAPを使ってRPCをやろうとするためには、そのランタイムの使い方を覚えればよい。ランタイムがメソッド・インターフェイスをSOAPに変換してサーバと通信をしてくれるからである。

 後半は、JavaプログラムによってSOAPを使うためのランタイムであるApache-SOAPを紹介し、簡単にその使い方を解説する。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。