Menu Close

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

概要

純粋な XML ペイロード形式は、SOAP エンベロープのオーバーヘッドなしでストレート XML ドキュメントを使用してサービスがデータを交換できるようにすることで、SOAP バインディングの代替手段を提供します。

XML バインディング namespace

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 バインディング namespace」 を参照してください。
  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 ドキュメントのルートノードとして機能する要素の 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 ドキュメントは pairNameentryNum の 2 つのルート要素があるため無効です。

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

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

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

例10.4 rootNode が設定された XML バインディング

<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 バインディング」 で定義した出力メッセージに、入力メッセージとは異なるルート要素を持たせる場合は、例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>