第10章 XML ドキュメントの使用

概要

Pure XML ペイロードフォーマットは、SOAP エンベロープのオーバーヘッドなしでシンプルな XML ドキュメントを使用してサービスをデータの交換を可能にすることで、SOAP バインディングの代替手段を提供します。

XML バインディング名前空間

XML 形式のバインディングを記述するために使用される拡張機能は namespace http://cxf.apache.org/bindings/xformat で定義されます。Apache CXF ツールは、接頭辞 xformat を使用して XML バインディングエクステンションを表します。コントラクトに次の行を追加します。

xmlns:xformat="http://cxf.apache.org/bindings/xformat"

ハンドエディティング

インターフェイスを純粋な XML ペイロードフォーマットにマッピングするには、以下を行います。

  1. namespace 宣言を追加して、XML バインディングを定義するエクステンションを追加します。「XML バインディング名前空間」を参照してください。
  2. XML バインディングを保持するための標準 WSDL binding 要素をコントラクトに追加し、バインディングに一意の name を付け、バインドされたインターフェイスを表す WSDL portType 要素の名前を指定します。
  3. xformat:binding 子要素を binding 要素に追加し、メッセージが SOAP エンベロープなしで純粋な XML ドキュメントとして処理されることを特定します。
  4. 必要に応じて、xformat:binding 要素の rootNode 属性を有効な QName に設定します。rootNode 属性の影響の詳細は、「ネットワーク上の XML メッセージ」 を参照してください。
  5. バインドされたインターフェイスで定義された各操作に対して、標準の WSDL operation 要素を追加して、操作のメッセージのバインディング情報を保持します。
  6. バインディングに追加された操作ごとに inputoutput、および fault 子要素を追加して、操作によって使用されるメッセージを表します。

    これらの要素は、論理操作のインターフェイス定義で定義されたメッセージに対応します。

  7. オプションで、有効な rootNode 属性を持つ xformat:body 要素を、追加された inputoutput、および fault 要素に追加して、バインディングレベルで設定された rootNode の値をオーバーライドします。
注記

void を返す操作の出力メッセージなど、メッセージのパートがない場合は、ネットワークで書き込んだメッセージが有効な空の XML ドキュメントであるように、メッセージの rootNode 属性を設定する必要があります。

ネットワーク上の XML メッセージ

インターフェイスのメッセージを SOAP エンベロープを使わずに XML 文書として渡すように指定する場合、メッセージがワイヤー上に書かれるときに有効な XML 文書を形成するように注意する必要があります。また、XML ドキュメントを受信する Apache CXF 参加者が Apache CXF によって生成されたメッセージを認識できるようにする必要があります。

両問題を解決する簡単な方法は、グローバル xformat:binding 要素または個別のメッセージの xformat:body 要素のいずれかで、オプションの rootNode 属性を使用することです。rootNode 属性は、Apache CXF が生成した XML ドキュメントの root ノードとして機能する要素の QName を指定します。rootNode 属性が設定されていない場合、Apache CXF は doc スタイルのメッセージを使用する際はルート要素としてメッセージ部分のルート要素を使用し、rpc スタイルのメッセージを使用する際はルート要素としてメッセージ部分の名前を使用する要素を使用します。

たとえば、rootNode 属性が設定されていない場合、例10.1「有効な XML バインディングメッセージ」 で定義されたメッセージは、ルート要素 lineNumber を持つ XML ドキュメントを生成します。

例10.1 有効な XML バインディングメッセージ

<type ... >
  ...
  <element name="operatorID" type="xsd:int"/>
  ...
</types>
<message name="operator">
  <part name="lineNumber" element="ns1:operatorID"/>
</message>

1 つの部分を持つメッセージでは、rootNode 属性が設定されていなくても、Apache CXF は常に有効な XML ドキュメントを生成します。ただし、例10.2「無効な XML バインディングメッセージ」 のメッセージは、無効な XML ドキュメントを生成します。

例10.2 無効な XML バインディングメッセージ

<types>
  ...
  <element name="pairName" type="xsd:string"/>
  <element name="entryNum" type="xsd:int"/>
  ...
</types>

<message name="matildas">
  <part name="dancing" element="ns1:pairName"/>
  <part name="number" element="ns1:entryNum"/>
</message>

XML バインディングで指定された rootNode 属性がない場合、Apache CXF は 例10.2「無効な XML バインディングメッセージ」 で定義されたメッセージに対して 例10.3「無効な XML ドキュメント」 のような XML ドキュメントを生成します。生成された XML ドキュメントは、pairName および entryNum の 2 つのルート要素があるため無効です。

例10.3 無効な XML ドキュメント

<pairName>
  Fred&Linda
</pairName>
<entryNum>
  123
</entryNum>

例10.4「rootNode が設定された XML Binding」 に示されているように、rootNode 属性を設定すると、Apache CXF は指定されたルート要素の要素をラップします。この例では、rootNode 属性はバインディング全体に対して定義され、ルート要素に entrants という名前を指定しています。

例10.4 rootNode が設定された XML Binding

<portType name="danceParty">
  <operation name="register">
    <input message="tns:matildas" name="contestant"/>
  </operation>
</portType>

<binding name="matildaXMLBinding" type="tns:dancingMatildas">
  <xmlformat:binding rootNode="entrants"/>
  <operation name="register">
    <input name="contestant"/>
    <output name="entered"/>
</binding>

入力メッセージから生成された XML ドキュメントは 例10.5「rootNode 属性を使用して生成された XML ドキュメント」 に似ています。XML ドキュメントにはルート要素が 1 つしかないことに注意してください。

例10.5 rootNode 属性を使用して生成された XML ドキュメント

<entrants>
  <pairName>
    Fred&Linda
  <entryNum>
    123
  </entryNum>
</entrants>

バインディングの rootNode 属性設定の上書き

また、メッセージバインディング内の xformat:body 要素を使用して、個別のメッセージの rootNode 属性を設定したり、特定のメッセージのグローバル設定をオーバーライドしたりすることもできます。たとえば、例10.4「rootNode が設定された XML Binding」 で定義した出力メッセージに、入力メッセージとは異なるルート要素がある場合、例10.6「xformat:body の使用」 に示されるようにバインディングのルート要素を上書きできます。

例10.6 xformat:body の使用

<binding name="matildaXMLBinding" type="tns:dancingMatildas">
  <xmlformat:binding rootNode="entrants"/>
  <operation name="register">
    <input name="contestant"/>
    <output name="entered">
      <xformat:body rootNode="entryStatus" />
    </output>
  </operation>
</binding>