サービスインタフェースにおける xsd:any による XML ドキュメントの記述

Sean BrydonSmitha KangathSameer Tyagi

課題

クライアントとサービスが XML ドキュメントを交換する Web サービスとの対話のデザインでは、サービスインタフェース内の XML ドキュメントを記述する型を選択する必要があります。この型の選択は、多くのことに影響します。選択された型は、サービスを記述した WSDL ファイルばかりでなく、サービス実装のコードにも反映されます。J2EE[tm] プラットフォーム (Java[TM] 2 Platform, Enterprise Edition) 1.4 アプリケーションでは、注文書やインボイスなどの XML ドキュメントの交換に、JAX-RPC (Java API for XML-based RPC) を使用します。 サービスインタフェースをデザインするときの XML ドキュメントを記述する型の選択肢は数多くあります。
この課題の対処法では、ドキュメント指向のサービスで xsd:any を用いて XML ドキュメントを記述する際のデザイン時の考慮事項に焦点を当てています。これらの対処法については、ドキュメント指向のサービスエントリを参照してください。

対処法

クライアントサービスの間で交換される XML ドキュメントを xsd:any を含む XML フラグメントを用いて記述する際の問題点をいくつか考えてみましょう。サービスインタフェースで交換される XML ドキュメントを xsd:any で記述する、この対処法は、サービスエンドポイントが多くの型のドキュメントを受信する可能性があり、それぞれのドキュメントが専用のスキーマを持っている場合に非常に有用です。どのような型のドキュメントでも受信するインタフェースをデザインできます。これは、ブローカまたはより汎用性の高いサービスインタフェースをデザインするときに役立ちます。xsd:any 型は基本的にワイルドカードであるため、同じオペレーションでスキーマが異なるドキュメントを受信する場合の型として利用できます。WSDL インタフェースで、受信する XML ドキュメントの型として xsd:any を指定するため、WSDL には、サービスが予想するドキュメントのスキーマは含まれません。このため、サービスのクライアント側は、補助ドキュメントなどの別の仕組みを見つけて、予想される一群のドキュメントの型を特定する必要があります。このサービス実装では、予想される一群のドキュメントを妥当性検査、処理し、予想していないスキーマのドキュメントのケースにも対処するコードを記述する必要があります。これとは異なり、このドキュメントの対処法では、WSDL ファイルで、サービスが使用するドキュメントに対するスキーマ定義型の使用を指定します。一言で言えば、xsd:any を使用するこの対処法は、サービスオペレーションでさまざまな組み合わせの XML ドキュメントが使用される一般的なオペレーションに有用です。

対処法: xsd:any を含む XML フラグメントによる XML ドキュメントの記述

XML スキーマでは、ワイルドカードの <xsd:any> 要素を利用することによって、スキーマが指定していない要素で複合型を拡張することができます。この <xsd:any> 要素は、実際にはスキーマで複合型の内容を定義する必要がない場合にも役立つことがあります。たとえばサービスオペレーションで複数の型の注文書 XML ドキュメントを受信する可能性があり、注文書のそれぞれに異なるスキーマが定義されている状況を考えてみましょうj。この場合は、サービスインタフェースで要素の注文書ドキュメント型を <any> と記述すると便利です。そうすることによってエンドポイントの汎用性が増します。このことはまた、サービス実装コードが、自身が受け取る XML ドキュメントの型を特定し、その型に応じて XML ドキュメントを正しく処理する必要があることを意味します。<any> を利用することによってサービスオペレーションの汎用性が増すため、作成するコードで対処できる必要があります。コード例 1 の WSDL ファイルに、<any> 要素を含む、型 submitPO が定義されていることに注意してください。これは、別の要素宣言内に <any> をラップしているようなものです。この submitPO 型は、オペレーションが注文書を送信する際に、サービスインタフェース内で使用されます。(要素名の submitPO とオペレーション名 submitPO が同じであることに注意してください。これは、単に、WSDL で、これらの名前の一致規則の指定に、ラップされたスタイルを使用しているためです)。このサービスの XML では、受信するドキュメントに任意の要素を持たせることができます。

<types>
  <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:AnyPurchaseOrderService">

    <complexType name="submitPO">
      <sequence>
          <any/>                       
      </sequence>
    </complexType>   
    <element name="submitPO" type="tns:submitPO"/>
  </schema>
</types>

<message name="AnyPurchaseOrderServiceSEI_submitPO">
  <part name="parameters" element="tns:submitPO"/>
</message>
 
...

<portType name="AnyPurchaseOrderServiceSEI">
  <operation name="submitPO">
      <input message="tns:AnyPurchaseOrderServiceSEI_submitPO"/>
      ...
  </operation>
</portType>

コード例 1: サービスオペレーションの入力パラメータでの <any> の使用法を示す WSDL コード例

JAX-RPC では、xsd:any スキーマ型要素を使用して要素ワイルドカードが表わされている場合、この複合型のマッピングは JavaBeans[tm] コンポーネントにマッピングされます。maxOccurs=1 の <any> 要素が存在すると、_any という追加のプロパティーが生成され、1 つの javax.xml.soap.SOAPElement にマッピングされます (maxOccurs が 1 より大きい場合は、javax.xml.soap.SOAPElement の配列にマッピングされる)。また、JAX-RPC では、XML スキーマ型に対する標準の Java マッピングがない場合、リテラル表現を持つメッセージ部は、XML ドキュメントフラグメントと見なされ、マッピングされます。XML と Java 間のマッピングでは、インタフェース javax.xml.soap.SOAPElement を使用して、wsdl:operation 要素の Java マッピングでリテラルメッセージ部を表します。このため、受信するドキュメントに <any> を使用しているコード例 1 に示すような WSDL ファイルから Java インタフェースを生成すると、コード例 2 に示すような type SubmitPO 型のラッパークラスがJava インタフェースに含まれることがあります。この場合、このインタフェースの Java 実装では、SubmitPO パラメータで取得メソッド get_any() を呼び出して、中にラップされている SOAPElement を取得する必要があります。この追加の呼び出しステップは少し不便ですが、大きな問題ではありません。

public interface AnyPurchaseOrderServiceSEI extends Remote {
    public SubmitPOResponse submitPO(SubmitPO parameters) throws
        InvalidPOException,  java.rmi.RemoteException;
}

コード例 2: Web サービスへのアクセスに使用するサービスインタフェース

参考資料

この項目に関する詳細は、次の資料を参照してください。

© Sun Microsystems 2005. All of the material in The Java BluePrints Solutions Catalog is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.