サービスインタフェースにおけるスキーマ定義型による XML ドキュメントの記述: デザインの詳細

java.net 主催の bpcatalog プロジェクトにあるドキュメント指向のアプリケーションは、ドキュメント中心のインタフェースとエンドポイントのデザインでドキュメント型としてドキュメントスキーマを使用する方法の具体例です。このアプリケーションには、スキーマ定義型として XML ドキュメントを使用するようにデザインされたサービスエンドポイントがあります。XML ドキュメントは、クライアントが送信する注文書で表されます。このアプリケーションは、注文書のスキーマがサービスインタフェースの一部である注文書を受け付けるように注文書サービスをデザインする具体的な方法を表しています。

このアプリケーションは、3 つの主要エンティティーで構成されています。

サービスの WSDL ファイル

WSDL ファイルは Web サービスの記述です。開発スタイルとしては、WSDL から始めて、そこから必要な Java クラスを生成するスタイルを採用しました。このため、WSDL のメッセージ部に適切な型を選択することは非常に重要です。これらの型が、生成される Java コードに含まれるパラメータの型になります。注文書スキーマが独立したファイルにあり、WSDL の中からインポートされることに注意してください。また、WSDL ファイル内にアプリケーション定義のサービス例外が宣言されていることにも注意してください。コード例 1 は、この サービスの WSDL からの抜粋です。

<types>
   <schema targetNamespace="urn:SchemaDefinedPurchaseOrderService" 
   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">
   <xsd:import namespace="http://java.sun.com/blueprints/ns/po" schemaLocation="PurchaseOrder.xsd"/>
   <element name="submitPO">
    <complexType>
       <sequence>
            <element name="inputDoc" type="pons:PurchaseOrder" nillable="true"/>                       
      </sequence>
    </complexType>
   </element>
   <element name="submitPOResponse">
    <complexType>
      <sequence>
            <element name="result" type="string" nillable="true"/>                       
      </sequence>
    </complexType>
   </element>
   <element name="InvalidPOException">
    <complexType>
      <sequence>
        <element name="message" type="string" nillable="true"/>                   
      </sequence>
    </complexType>
   </element>                             
   </schema>
   </types>
  <message name="SchemaDefinedPurchaseOrderServiceSEI_submitPO">
    <part name="parameters" element="tns:submitPO"/>
 </message>
  <message name="SchemaDefinedPurchaseOrderServiceSEI_submitPOResponse">
    <part name="result" element="tns:submitPOResponse"/>
 </message>
  <message name="InvalidPOException">
   <part name="InvalidPOException" element="tns:InvalidPOException"/>
  </message>
  <portType name="SchemaDefinedPurchaseOrderServiceSEI">
    <operation name="submitPO">
      <input message="tns:SchemaDefinedPurchaseOrderServiceSEI_submitPO"/>
      <output message="tns:SchemaDefinedPurchaseOrderServiceSEI_submitPOResponse"/>
      <fault name="InvalidPOException" message="tns:InvalidPOException"/>
    </operation>
  </portType>
コード例 1: サービスの WSDL からの抜粋

サービスインタフェースに含まれる注文書ドキュメントを見てみましょう。コード例 2 は、注文書スキーマを示しています。このファイルは、<xsd:import namespace="http://java.sun.com/blueprints/ns/po" schemaLocation="PurchaseOrder.xsd"/> 文を使用して、コード例 1 の WSDL ファイルにインポートされます。
注文書スキーマをインポートすることによって、WSDL ファイルは、サービスインタフェース内でこの型を使用し、交換するドキュメントを記述することができます。

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://java.sun.com/blueprints/ns/po" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://java.sun.com/blueprints/ns/po" elementFormDefault="qualified">
  <xsd:element name="PurchaseOrder" type="PurchaseOrder"/>
    <xsd:complexType name="Address">
        <xsd:sequence>
            <xsd:element name="street" type="xsd:string" nillable="false"/>
            <xsd:element name="city" type="xsd:string" nillable="false"/>
            <xsd:element name="state" type="xsd:string" nillable="false"/>
            <xsd:element name="postalCode" type="xsd:string" nillable="false"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="LineItem">
        <xsd:sequence>
            <xsd:element name="itemId" type="xsd:string" nillable="false"/>
            <xsd:element name="price" type="xsd:float" nillable="false"/>
            <xsd:element name="quantity" type="xsd:int" nillable="false"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="PurchaseOrder">
        <xsd:sequence>
            <xsd:element name="poId" type="xsd:string" nillable="false"/>
            <xsd:element name="createDate" type="xsd:date" nillable="false"/>
            <xsd:element name="shipTo" type="Address" nillable="false"/>
            <xsd:element name="billTo" type="Address" nillable="false"/>
            <xsd:element name="items" type="LineItem" nillable="false" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>
コード例 2: 注文書スキーマ

サービスエンドポイントインタフェース

このサンプルアプリケーションの開発は WSDL から始めているため、サービスエンドポイントインタフェースは、WSDL に含まれる情報に基づいて生成されます。サービスエンドポイントインタフェースには、PurchaseOrder オブジェクトを受け付ける submitPO() メソッドがあります。PurchaseOrder クラスが生成され、これは、WSDL ファイルにインポートされる注文書スキーマに対応します。また、アプリケーション定義の例外 InvalidPOException も WSDL から生成されます。

public interface SchemaDefinedPurchaseOrderServiceSEI extends Remote {
    public String submitPO(PurchaseOrder inputDoc) throws
        InvalidPOException, RemoteException;
}

コード例 3: サービスエンドポイントインタフェース

Java エンドポイント実装

このアプリケーションの場合は、EJB コンポーネントを使用して、サービスインタフェースを実装しています。代わりに、Web コンポーネントを使用してエンドポイントを実装することもできます。どちらでも問題ありません。getPoId() メソッドは、単にクライアントに注文書 ID を返すだけであることに注意してください。実際には、クライアントに結果を返す前に何らかの仕事を行う必要があるでしょう。また、アプリケーションに固有の例外のスローを理解するため、このエンドポイントは注文書 ID が固有の番号かどうかをチェックし、この条件が満たされない場合は、例外をスローします。エンドポイント実装クラスは、次のようになります。

public class SchemaDefinedPurchaseOrderServiceBean implements SessionBean {  
    private SessionContext sc;  
    public SchemaDefinedPurchaseOrderServiceBean(){}  

    public String submitPO(PurchaseOrder po) throws InvalidPOException, RemoteException {      
        // アプリケーションに固有の例外のスローを紹介することのみを目的としたコード
        if(po.getPoId().equals("100"))
            throw new InvalidPOException("Invalid ID for the purchase order!!! " +
                    "For demo purposes, we throw " +
                    "an application defined exception for the ID value of 100.");      
        // PO ID を抽出して、クライアントに返す
        return po.getPoId();
    }  

    // ライフサイクルメソッド
    public void ejbCreate() throws CreateException {}  
    public void setSessionContext(SessionContext sc) {
        this.sc = sc;
    }  
    public void ejbRemove(){}  
    public void ejbActivate() {}  
    public void ejbPassivate() {}
}
コード例 4: エンドポイント実装

配備記述子

J2EE 内の Web サービスは、WAR あるいは EAR ファイルなどの配備モジュールにパッケージングされます。このアプリケーションでは、EAR ファイルとしてパッケージングしました。Web サービスエンドポイントを移植可能な形式でパッケージングするには、Java クラスばかりでなく、いくつかの配備記述子が必要です。以下は、エンドポイント配備記述子からの抜粋です。

<enterprise-beans>
  <session>
    <ejb-name>SchemaDefinedPurchaseOrderServiceBean</ejb-name>
    <service-endpoint>com.sun.j2ee.blueprints.objectposervice.SchemaDefinedPurchaseOrderServiceSEI</service-endpoint>
    <ejb-class>com.sun.j2ee.blueprints.objectposervice.SchemaDefinedPurchaseOrderServiceBean</ejb-class>
    <session-type>Stateless</session-type>
    <transaction-type>Container</transaction-type>
  </session>
</enterprise-beans>
コード例 5: ejb-jar.xml 配備記述子からの抜粋

ejb-jar.xml 内でサービスエンドポイントインタフェースが <service-endpoint> として定義されていることに注意してください。
このエンドポイントにはまた、次のような Web サービス配備記述子ファイル webservices.xml も必要です。

<webservice-description>   
  <webservice-description-name>SchemaDefinedPurchaseOrderService</webservice-description-name>   
  <wsdl-file>META-INF/wsdl/SchemaDefinedPurchaseOrderService.wsdl</wsdl-file>   
  <jaxrpc-mapping-file>META-INF/schemadefinedpurchaseorderservice-mapping.xml</jaxrpc-mapping-file>
  <port-component>
    <description>port component description</description>     
    <port-component-name>SchemaDefinedPurchaseOrderService</port-component-name>
    <wsdl-port xmlns:PurchaseOrderns="urn:SchemaDefinedPurchaseOrderService">
      PurchaseOrderns:SchemaDefinedPurchaseOrderServiceSEIPort
    </wsdl-port>
    <service-endpoint-interface>     
      com.sun.j2ee.blueprints.objectposervice.SchemaDefinedPurchaseOrderServiceSEI
    </service-endpoint-interface>
    <service-impl-bean>     
      <ejb-link>SchemaDefinedPurchaseOrderServiceBean</ejb-link>
    </service-impl-bean>
  </port-component>
</webservice-description>
コード例 6: webservice.xml 配備記述子からの抜粋

Web サービス配備記述子ファイルには、WSDL ファイルや JAX-RPC マッピングファイルなどの名前や、サービスエンドポイントインタフェース名、サービス実装クラス名などのサービスに関する情報が含まれます。
© 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.