日本オラクル
プロダクトSC本部 テクノロジーSC部
佐藤 直生




 はじめに

前回は、WSDLの基本的な構造を概観しました。今回は、前回説明を割愛したMEP(メッセージ交換パターン)や、SOAPにおけるスタイルとエンコーディングについて見ていきましょう。


 MEP(メッセージ交換パターン)

ここでは、Webサービスにおけるメッセージ交換をどのように考えるべきか見てきます。

まず、SOAP 1.1の「2. SOAPメッセージ交換モデル」から引用します。

SOAPのメッセージは基本的には送信者から受信者への一方通行で伝達される。しかし、前の例のようにリクエスト/レスポンスのようなパターンを実現するためにSOAPメッセージを組み合わせて使うことがしばしばある。

当たり前と言えば当たり前ですが、最も基本的なメッセージ交換の形式は、送信者から受信者への一方向のメッセージ送信です。これを組み合わせることで、いくつかのメッセージ交換のパターンが定義されます。

一方、WSDL 1.1では、ポートタイプに含まれるオペレーションに対して、次の4つのメッセージ交換パターンを表現できます。WSDL 1.1の「2.4 ポート・タイプ」から引用します。

WSDLには、端点がサポートできる4つの転送プリミティブがあります。
  • 一方向(One-way): 端点はメッセージを受信します。
  • 要求/応答(Request-response): 端点はメッセージを受信して、対応するメッセージを送信します。
  • 送信請求/応答(Solicit-response): 端点はメッセージを送信し、対応するメッセージを受信します。
  • 通知(Notification): 端点はメッセージを送信します。
一方向 (One-way) の場合、WSDLの<operation>要素には、SOAPリクエストに相当する<input>のみが含まれます。

<definitions .....>
  <portType .....>
    <operation .....>
       
                                          
<input name="....." message="....."/>
    </operation>
  </portType >
</definitions>
                                        

要求/応答(Request-response)の場合、WSDLの<operation>要素には、SOAPリクエストに相当する<input>、SOAPレスポンスに相当する<output>、エラー発生時のSOAPレスポンスに相当する<fault>が含まれます。前回ご紹介したWSDLは、この要求/応答(Request-response)パターンになっています。(ここでは、SOAPリクエスト/レスポンスに結び付けて説明していますが、前回見たようにWSDLのオペレーション自体は抽象的なものであり、(SOAPバインディングなどの)特定のバインディングに依存した具体的な定義情報をは直接は関係ないことに注意しましょう。)

<definitions .....>
  <portType .....>
    <operation .....>
       
                                          
<input name="....." message="....."/>
<output name="....." message="....."/>
<fault name="....." message="....."/>
</operation> </portType > </definitions>

送信請求/応答(Solicit-response)は、メッセージ交換を開始するのがエンドポイント(端点)である点で、要求/応答(Request-response)とは逆のパターンになっています。SOAPで言えば、SOAPサービス(Webサービス)からWebサービス・クライアントに対してSOAPメッセージを送信し、その応答を受信する、ということです。

<definitions .....>
  <portType .....>
    <operation .....>
       
                                          
<output name="....." message="....."/>
<input name="....." message="....."/>
<fault name="....." message="....."/>
</operation> </portType > </definitions>

通知(Notification)は、一方向(One-way)の逆のパターンです。SOAPで言えば、SOAPサービス(Webサービス)からWebサービス・クライアントに対してSOAPメッセージを送信する、ということです。

<definitions .....>
  <portType .....>
    <operation .....>
       
                                          
<output name="....." message="....."/>
    </operation>
  </portType >
</definitions>
                                        

WSDLではメッセージ交換パターンを表現できるわけですが、実際のWebサービス実装で広く使われるメッセージ交換パターンは、一方向(One-way)と要求/応答(Request-response)の2つだけです。Webサービスの相互運用性を向上するためのプロファイルであるWS-I Basic Profile 1.0では、送信請求/応答(Solicit-response)と通知(Notification)の使用を禁止しています。

5.4.2 Allowed operations(許容されるオペレーション)

Solicit-Response及びNotificationは WSDL 1.1では十分に規定されておらず、さらに、WSDL 1.1はそれらに対するバインディングも定義していない。

[R2303] DESCRIPTIONはwsdl:portTypeの定義にSolicit-Response及びNotification型のオペレーションを使用してはならない(MUST NOT)。

2つのエンドポイント間のメッセージ交換を考えてみましょう。要求/応答(Request-response)は、単に一方のエンドポイントが他方のエンドポイントにリクエストを送信し、そのレスポンスを受信する同期型の通信であると捉えられます。要求/応答(Request-response)は、WSDLのオペレーションにおける抽象的な定義なので、必ずしも特定のプロトコルに関連しているわけではありません。とはいえ、最も広く使われているSOAP over HTTP(HTTPトランスポートを使うSOAPバインディング)では、HTTPリクエスト/レスポンスにSOAPリクエスト/レスポンスが綺麗にマッピングできます。

一方向(One-way)はどうでしょうか? エンドポイントAがエンドポイントBに一方向のリクエストを送信し、その後、エンドポイントBがエンドポイントAに再度一方向のリクエスト(コールバック)を送信するシナリオを考えてみましょう。これは、非同期型の通信と考えることができますね。


 SOAPにおけるスタイルとエンコーディング

続いて、前回詳しく説明しなかったスタイルやエンコーディングについて、考えてみましょう。

まず、エンコーディングを取り上げます。エンコーディング(符号化)とは、送信したいデータをXMLとして表現する(シリアライズする)際の手法のことです。SOAP通信では、SOAPメッセージのボディ内にXML形式でデータが送信されます。そのため、SOAPメッセージの送信者と受信者は、どのようにデータをXML化しているかに関して合意している必要があります。そうしないと、送信者がシリアライズしたSOAPボディを、受信者が正しくXMLを解釈できない(デシリアライズできない)ことになってしまいます。

<soap:body>要素(および<soap:fault>、<soap:header>、<soap:headerfault>の各要素)のuse属性では、"literal"(リテラル)か "encoded"(エンコード)を指定できます。「リテラル」とは、特定のエンコーディング・スキームを使わず、XML Schemaを直接使ってシリアライズすることです。逆に、「エンコード」とは、特定のエンコーディング・スキームを使ってデータをXMLとして表現することです。通常使われるエンコーディング・スキームは、SOAP 1.1仕様の「5. SOAP符号化」で定義されているSOAPエンコーディングです。使用するエンコーディングは、<soap:body>などの要素のencodingStyle属性で指定します。

一方、スタイルとは、SOAPバインディング(<soap:binding>要素)、またはSOAPバインディングのオペレーション(<soap:operation>要素)のstyle属性を指します。style属性の取り得る値は、"rpc"(RPC指向)か"document"(ドキュメント指向)です。

では、RPC指向とは何でしょうか? 昔ながらのRPC(リモート・プロシージャ・コール)は、ローカル・マシンやローカル・プロセスの外にある リモートのプロセスに対して、プロシージャやメソッドなどの機能を呼び出して、何かしらの処理を実行し、その結果を受け取ることです。RPCはプロシージャ・コールですので、入力パラメータ (引数) を渡し、特定のプロシージャを呼び出し、出力パラメータ(戻り値)を受け取るという同期型の通信になります。Sun RPCやWindowsのRPCもそうですし、CORBA、RMI/EJB、DCOMなどの分散オブジェクト間のメソッドコールもRPCの一種(拡張)と捉えることもできますね。

SOAP/WSDLにおけるRPC指向とは、SOAPメッセージをつかってRPC機能を実現することです。同期型のRPCをSOAPで実現するこということは、要求/応答(Request-response)型のメッセージ交換パターンを使うことになります。そして、RPCのプロシージャに相当するものが、WSDLで定義したオペレーションになるわけです。オペレーションはJavaで言えばメソッドのようなものだということは、前回説明しましたね。

RPC指向の場合、SOAP 1.1仕様の「7. RPCのためのSOAPの使用」に規定されている規則に従う必要があります。SOAP 1.1仕様の「7.1 RPCとSOAP Body」を引用します。

7.1 RPCとSOAP Body

RPCメソッドコールとレスポンスは共に、以下の表現を使用して、SOAP Body要素(4.3節を参照)で運ばれる。

メソッド呼び出しは、構造体としてモデル化される。
メソッド呼び出しは、各[in]または[in/out]パラメータに対するアクセサを含む単一の構造体と見なされる。その構造体は、メソッド名とまったく同じに、名前および型が付けられる。
各[in]または[in/out]パラメータは、パラメータの名前に対応する名前と、パラメータの型に対応する型を持ったアクセサと見なされる。これらは、メソッドシグニチャと同じ順番で現れる。
メソッドレスポンスは、構造体としてモデル化される。
メソッドレスポンスは、戻り値と各[out]または[in/out]パラメータに対するアクセサを含む単一の構造体と見なされる。最初のアクセサは戻り値であり、その後にパラメータがメソッドシグニチャと同じ順番で現れる。
各パラメータアクセサは、パラメータの名前に対応する名前と、パラメータの型に対応する型を持つ。戻り値アクセサの名前は重要ではない。同様に、構造体の名前も重要ではない。しかし、慣例では、メソッド名の後に文字列"Response"を付加したものをその名前とする。
メソッド違反は、 SOAP Fault要素(4.4節を参照)を使用して符号化される。プロトコルバインディングがその表現に対して更なる規則を追加したのであれば、それらもまた従われなければならない。

前述のように、メソッドとレスポンスの構造体は、5節の規則に従って符号化される。そうでなければ、encodingStyle属性(4.1.1節を参照)を使用して、別の符号化が指定される。

アプリケーションは、パラメータが欠けた状態でリクエストを処理してもよいし、違反を返してもよい。

結果は成功を示し、違反は失敗を示すため、メソッドレスポンスが結果と違反を共に含むことはエラーである。

RPC指向のSOAPメッセージの具体例は、後ほどご紹介します。なお、RPC指向のSOAPレスポンスに含まれる要素名として、WSDLのオペレーション名に "Response" を付加したものを使うことは、SOAP 1.1では単なる「慣習」ですが、WS-I Basic Profile 1.0では "MUST" になっています。

5.6.19 Response Wrappers(レスポンスのラッパー)

WSDL 1.1の3.5節は、RPCレスポンスのラッパー要素がwsdl:operationの名前と同じでなければならないと解釈することも可能である。

[R2729] rpc-literalバインディングで記述されたレスポンスのMESSAGEは、ラッパー要素の名前を、対応するwsdl:operationの名前の後ろに "Response" という文字列を付けたものとしなければならない(MUST)。

一方、ドキュメント指向とは何でしょうか? RPC指向では、SOAPメッセージに含まれるXMLは、入出力パラメータをラッピングした単なる構造体に過ぎません。ですが、より意味のあるXML文書をやり取りするために、Webサービスの使うことも考えられますよね? 業界によらない、あるいは業界に特化したXMLベースの仕様は数多く策定されつつあり、結果としてビジネス上意味のある情報をXML文書として扱う流れも広がりつつあります。ドキュメント指向では、このXML文書をSOAPメッセージに載せてやり取りできるのです。ドキュメント指向のWebサービスについては、次回以降取り上げようと思っています。

さて、リテラルまたはエンコードと、スタイル(RPC指向、またはドキュメント指向)を組み合わせて、理論的には次の4つのスタイルが存在し得ます。

RPC/エンコード
RPC/リテラル
ドキュメント/リテラル
(ドキュメント/エンコード)

先ほども紹介したWS-I Basic Profile 1.0では、リテラルの使用を推奨しており、エンコードの使用を禁止しています。つまり、RCP指向であればRPC/リテラル、ドキュメント指向であればドキュメント/リテラルを使うべき、ということです。実は、Webサービスが登場した初期の頃は、RPC/エンコードが主流でした。ですが、Webサービス実装間の相互運用性をテストした結果、配列の扱いなどSOAPエンコーディングによって引き起こされる問題がいくつかあることが分かりました。そのため、相互運用性の向上を狙うWS-I Basic Profileでは、面倒なSOAPエンコーディングの代わりにXML Schemaだけで構造を表現するリテラルを推奨するようになったのです。

4.1.7 SOAP encodingStyle Attribute(SOAPのencodingStyle属性)

soap:encodingStyle属性は、データをXMLにエンコーディングする際に特定のスキームを使うことを示すのに使われてきた。しかし、この機能はXML名前空間を使っても実現できるので、複雑さを導入してしまう。そこで、このプロファイルは、literalの、エンコードされないXMLのほうを優先している。

[R1005] MESSAGEは、名前空間名 (namespace name) が "http://schemas.xmlsoap.org/soap/envelope/" である要素のいずれにもsoap:encodingStyle属性を含んではならない(MUST NOT)。

[R1006] MESSAGEは、soap:Body要素の子要素のいずれにもsoap:encodingStyle属性を含んではならない(MUST NOT)。

[R1007] rpc-literalバインディングで記述されるMESSAGEは、soap:Body要素の孫要素のいずれにもsoap:encodingStyle属性を含んではならない (MUST NOT)。

5.6.3 Consistency of style Attribute(style属性の整合性)

style が "document" か "rpc" かはwsdl:operationのレベルで指定されるので、個々のwsdl:operationに相異なるstyleをもつwsdl:bindingを許してしまう。これは、相互運用上の問題となる。

[R2705] DESCRIPTIONの中のwsdl:bindingは、rpc-literalバインディング又はdocument-literalバインディングのいずれかを使用しなければならない(MUST)。

5.6.4 Encodings and the use Attribute(エンコーディングとuse属性)

このプロファイルでは相異なるエンコーディングを(SOAPエンコーディングを含め)禁止している。

[R2706] DESCRIPTIONの中のwsdl:bindingは、すべてのsoapbind:body, soapbind:fault, soapbind:header及びsoapbind:headerfault要素に対して、use属性の値を "literal" としなければならない(MUST)。


説明ばかりでは分かりづらいので、ここからは具体的にWSDLやSOAPを眺めてみましょう。今回も、前回と同様、次の開発/実行環境を使っています。

 OC4J(Oracle Application Server Containers for J2EE) 10g 10.0.3 Developer Preview 2
- (JAX-RPC 1.1を含む)J2EE 1.4準拠のJ2EEコンテナ
- http://www.oracle.com/technology/tech/java/oc4j/
 Oracle JDeveloper 10g 9.0.5
- J2EE開発を完全にサポートしたJava IDE
- http://otn.oracle.co.jp/products/jdev/
- http://www.oracle.co.jp/tools/jdev1980/
 JAX-RPC Web Services for Oracle JDeveloper 10g Preview
- JAX-RPC開発を支援するOracle JDeveloper 10g向けの拡張機能(プラグイン)
- http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jaxrpc/


Webサービスの実装としても、前回同様、Javaインタフェース calc.Calc、Javaクラス calc.CalcImplを使います。

package calc;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Calc extends Remote 
{
  public int add(int a, int b) throws RemoteException;

  public int subtract(int a, int b) throws RemoteException;
}

package calc;
import java.rmi.RemoteException;

public class CalcImpl implements Calc 
{
  public int add(int a, int b) throws RemoteException
  {
    return a + b;
  }

  public int subtract(int a, int b) throws RemoteException
  {
    return a - b;
  }
}

JAX-RPCを使ってこのクラスを基にWebサービスを作成します。JDeveloperでは、RPC/エンコード、RPC/リテラル、ドキュメント/リテラルのWebサービスを作成できますので、それぞれを比較してみることにしましょう。

まずは、RPC/エンコードの場合です。JDeveloperが自動生成したWSDLのうち、"add"オペレーションに関連する部分だけ引用します。<soap:binding>要素の属性 style="rpc"と、<soap:body>要素の属性 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" および use="encoded" に注意しましょう。

<?xml version = '1.0' encoding = 'UTF-8'?>
<definitions name="CalcServiceRpcEnc" 
             targetNamespace="http://calc/"
             xmlns:tns="http://calc/" 
             xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  <types/>
  <message name="Calc_add">
    <part name="int_1" type="xsd:int"/>
    <part name="int_2" type="xsd:int"/>
  </message>
  <message name="Calc_addResponse">
    <part name="result" type="xsd:int"/>
  </message>
  .....
  <portType name="Calc">
    <operation name="add" parameterOrder="int_1 int_2">
      <input message="tns:Calc_add"/>
      <output message="tns:Calc_addResponse"/>
    </operation>
    .....
  </portType>
  <binding name="CalcBinding" type="tns:Calc">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"  
                                          
style="rpc"/>
    <operation name="add">
      <input>
        <soap:body  
                                          
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                    
                                          
use="encoded" namespace="http://calc/"/>
      </input>
      <output>
        <soap:body  
                                          
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                    
                                          
use="encoded" namespace="http://calc/"/>
      </output>
      <soap:operation soapAction=""/>
    </operation>
    .....
  </binding>
  <service name="CalcServiceRpcEnc">
    <port name="CalcPort" binding="tns:CalcBinding">
      <soap:address location="http://localhost:8888/calc/CalcServiceRpcEnc"/>
    </port>
  </service>
</definitions>
                                        

実際のSOAPリクエスト/レスポンスの例も載せておきましょう。(JDeveloperを使うと、簡単にSOAPリクエスト/レスポンスをキャプチャできます。)SOAPリクエストでもSOAPレスポンスでも、SOAPエンコーディング(env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/")を指定していることに注意しましょう。また、属性 xsi:type="xsd:int" によって、入出力パラメータの型情報を明示的に伝達していることにも注意しましょう。SOAPリクエストの<ns0:add>要素、SOAPレスポンスの<ns0:addResponse>要素がラッパー要素であり、その中に入出力パラメータが構造体として格納されていますね。

POST http://localhost:8888/calc/CalcServiceRpcEnc HTTP/1.1
Host: localhost:8888
SOAPAction: ""
Content-type: text/xml; charset="UTF-8"
Content-length: xxx

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
              xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" 
              xmlns:ns0="http://calc/" 
              env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <env:Body>
    <ns0:add>
<int_1 xsi:type="xsd:int">1</int_1>
<int_2 xsi:type="xsd:int">2</int_2>
</ns0:add>
</env:Body> </env:Envelope>

HTTP/1.1 200 OK
Date: Xxx, xx Xxx xxxx xx:xx:xx GMT
Server: Oracle Application Server Containers for J2EE 10g (10.0.3.0.0) - Developer Preview
Connection: Close
Content-Type: text/xml; charset="UTF-8"
Content-Length: xxx
SOAPAction: ""

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
              xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" 
              xmlns:ns0="http://calc/">
  <env:Body>
    <ns0:addResponse env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<result xsi:type="xsd:int">3</result>
</ns0:addResponse>
</env:Body> </env:Envelope>

次に、RPC/リテラルのWSDLの例です。<soap:body>要素の属性 use="literal" に注意しましょう。

<?xml version = '1.0' encoding = 'UTF-8'?>
<definitions name="CalcServiceRpcEnc" 
             targetNamespace="http://calc/"
             xmlns:tns="http://calc/" 
             xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  <types/>
  <message name="Calc_add">
    <part name="int_1" type="xsd:int"/>
    <part name="int_2" type="xsd:int"/>
  </message>
  <message name="Calc_addResponse">
    <part name="result" type="xsd:int"/>
  </message>
  .....
  <portType name="Calc">
    <operation name="add" parameterOrder="int_1 int_2">
      <input message="tns:Calc_add"/>
      <output message="tns:Calc_addResponse"/>
    </operation>
    .....
  </portType>
  <binding name="CalcBinding" type="tns:Calc">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
    <operation name="add">
      <input>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                   use="encoded" namespace="http://calc/"/>
      </input>
      <output>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                   use="encoded" namespace="http://calc/"/>
      </output>
      <soap:operation soapAction=""/>
    </operation>
    .....
  </binding>
  <service name="CalcServiceRpcEnc">
    <port name="CalcPort" binding="tns:CalcBinding">
      <soap:address location="http://localhost:8888/calc/CalcServiceRpcEnc"/>
    </port>
  </service>
</definitions>

そして、RPC/リテラルのSOAPリクエスト/レスポンスの例です。RPC/エンコードの例では存在したSOAPエンコーディングの指定がないことに注意しましょう。また、入出力パラメータの型情報は、WSDLとXML Schemaから分かるので、SOAPメッセージ内で伝達していないことにも注意しましょう。

.....
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
              xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xmlns:ns0="http://calc/">
  <env:Body>
    <ns0:add>
<int_1>1</int_1>
<int_2>2</int_2>
</ns0:add>
</env:Body> </env:Envelope>

.....
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
              xmlns:ns0="http://calc/">
  <env:Body>
    <ns0:addResponse>
<result>3</result>
</ns0:addResponse>
</env:Body> </env:Envelope>

最後に、ドキュメント/リテラルの例です。

SOAPリクエストの<ns0:addElement>要素、SOAPレスポンスの<ns0:addResponseElement>要素は、一見RPC指向の場合と似ていますが、実は違います。RPC指向の場合は、WSDLオペレーションと同じ名前のSOAPリクエストのラッパー要素、WSDLオペレーション名に"Response"を付加したSOAPレスポンスのラッパー要素、構造体として表される入出力パラメータなどの規則は、すべて決められたものです。

一方、ドキュメント指向では、SOAPボディに含まるXMLの構造は自由に決められます。実際、WSDLの<types>要素において、"add"型、"addResponse"型、<addElement>要素、<addResponseElement>要素を定義していますね。必要に応じて<types>要素のXML Schema定義を変更すれば、SOAPボディに含まれるXMLの構造も自由自在に変えることができるのです。

<?xml version = '1.0' encoding = 'UTF-8'?>
<definitions name="CalcServiceDocLit" .....>
  <types>
    <schema targetNamespace="http://calc/types" 
            xmlns:tns="http://calc/types"
            xmlns:soap11-enc="http://schemas.xmlsoap.org/soap/encoding/"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
            xmlns="http://www.w3.org/2001/XMLSchema">
      <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
      <complexType name="add">
        <sequence>
          <element name="int_1" type="int"/>
          <element name="int_2" type="int"/>
        </sequence>
      </complexType>
      <complexType name="addResponse">
        <sequence>
          <element name="result" type="int"/>
        </sequence>
      </complexType>
      .....
      <element name="addElement" type="tns:add"/>
<element name="addResponseElement" type="tns:addResponse"/>
..... </schema> </types> <message name="Calc_add"> <part name="parameters" element="ns2:addElement"/> </message> <message name="Calc_addResponse"> <part name="result" element="ns2:addResponseElement"/> </message> ..... <portType name="Calc"> <operation name="add"> <input message="tns:Calc_add"/> <output message="tns:Calc_addResponse"/> </operation> ..... </portType> <binding name="CalcBinding" type="tns:Calc"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="add"> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> <soap:operation soapAction=""/> </operation> ..... </binding> <service name="CalcServiceDocLit"> <port name="CalcPort" binding="tns:CalcBinding"> <soap:address location="http://127.0.0.1:8888/calc/CalcServiceDocLit"/> </port> </service> </definitions>

.....
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
              xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xmlns:ns0="http://calc/types">
  <env:Body>
    <ns0:addElement>
<int_1>1</int_1>
<int_2>2</int_2>
</ns0:addElement>
</env:Body> </env:Envelope>

.....
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
              xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" 
              xmlns:ns0="http://calc/types">
  <env:Body>
    <ns0:addResponseElement>
<result>3</result>
</ns0:addResponseElement>
</env:Body> </env:Envelope>


 おわりに

今回は、知っているようで意外に知られていないメッセージ交換パターン、エンコーディング、スタイルについて見てきました。次回は、今回の内容を踏まえて、複数のWebサービスを連携させてビジネスプロセスを定義するための言語 BPEL についてご紹介する予定です。お楽しみに!

[リファレンス]
 SOAP 1.1(日本語訳)
http://www.microsoft.com/japan/msdn/library/ja/jpwebwk/xml/general/soapspec.asp
 WSDL 1.1(日本語訳)
http://www.microsoft.com/japan/developer/workshop/xml/general/wsdl.asp
 WS-I Basic Profile 1.0(日本語訳)
http://www.ws-i.org/Profiles/Basic/2003-08/BasicProfile-1.0a-ja.html