ヘッダーをスキップ
Oracle Application Server Web Servicesアドバンスト開発者ガイド
10g(10.1.3.1.0)
B31869-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

7 Java値タイプのカスタム・シリアライズの実装

この章では、カスタム・シリアライズ・フレームワークAPIを説明します。このAPIを使用すると、スキーマ定義のXML型と、JAX-RPC値タイプの要件に準拠しておらずデフォルトのJAX-RPCシリアライズ・メカニズムでは処理できないJava値タイプ・クラス間で、Java値タイプをマッピングおよびシリアライズできます。このフレームワークは、デフォルト・マッピングを持つスキーマ型のカスタム・マッピングの実装にも使用できます。たとえば、フレームワークを使用して、xsd:dateTimeをデフォルト・マッピングjava.util.Calendarではなく、カスタム・クラスcom.hello.MyDateにマッピングできます。

カスタム・シリアライズ・フレームワークAPIは、Webサービスをトップダウン方式やボトムアップ方式で公開するため、またはスキーマからJava値タイプを生成してWebサービス・エンドポイントを公開するために、Java値タイプをシリアライズする際に使用できます。

OracleAS Web Servicesには、特定のJavaデータ型へのマッピングのサポートが組み込まれています。これらのJava値タイプのカスタム・マッピングを作成する必要はありません。


関連資料:


この章の内容は、次のとおりです。

カスタム・シリアライズ・フレームワークAPIの概要

Webサービスでカスタムまたは標準以外のJava値タイプを公開する場合、OracleAS Web Servicesには、Java値タイプをXML表現にシリアライズできるAPIが用意されています。oracle.webservices.databindingパッケージのSOAPElementSerializerインタフェースには、OracleAS Web Services JAX-RPC実装のプラッガブルなカスタム・シリアライザのインタフェースが定義されています。

public interface SOAPElementSerializer

SOAPElementSerializerのインスタンスにより、JavaオブジェクトはSOAPElementのXML表現にシリアライズされ、SOAPElementはJavaオブジェクトにデシリアライズされます。

このインタフェースには次のメソッドがあります。

インタフェースの実装には、デフォルトの引数を使用しないコンストラクタが必要です。SOAPElementSerializerの詳細は、『Oracle Application Server Web Services Java API Reference』で説明されています。

Webサービス開発におけるカスタム・シリアライズの使用方法

Webサービスでカスタム・シリアライズを使用するには、カスタムJava値タイプ・クラスのSOAPElementSerializerの実装を指定します。また、カスタムJava値タイプ・クラス、およびJava値タイプ・クラスと表現するXMLスキーマ型の間のマッピングを定義するXML構成ファイルも指定する必要があります。これは次の項で説明します。

カスタム・シリアライザの実装方法

この項では、Java値タイプ・クラスのカスタム・シリアライザの実装手順を説明します。

  1. XMLスキーマ型として表現するカスタムJava値タイプ・クラスを定義します。

  2. クラスのカスタム・シリアライザ実装を定義します。

  3. サービス・エンドポイント・インタフェースとその実装を定義します。

    トップダウン方式でWeb Servicesをアセンブルする場合、WebServicesAssemblerによりサービス・エンドポイント・インタフェースがWSDLから生成されます。ボトムアップ方式でWeb Servicesをアセンブルする場合、Javaサービス・エンドポイント・インタフェースを指定する必要があります。

  4. カスタムJava値タイプ・クラスを表現する際に使用されるスキーマ型を示すoracle-webservicesタイプ・マッピング構成のXMLファイルを作成します。

  5. カスタム・タイプをクライアント・コードに含めます。

この手順は、次の項で詳しく説明します。

カスタムJava値タイプ・クラスの定義方法

この項では、XMLスキーマ型へのマッピングに使用可能なカスタムJava値タイプ・クラスを説明します。


注意:

  • Webサービスでシリアライズが必要なJ2EE機能(EJBまたはJMSなど)を使用しない場合、カスタムJava値タイプ・クラスがシリアライズ可能である必要はありません。

  • 空のコンストラクタは不要です。プログラムで記述するシリアライザ実装により、対応するJava型のインスタンスが作成され、Javaオブジェクトのコンテンツが移入されます。これがカスタム・シリアライザを使用する理由です。XMLからJava、JavaからXMLへのマッピングを完全に制御できます。


例7-1に、カスタムJava値タイプ・クラスの定義を示します。JAX-RPCでは、xsd:dateTimejava.util.Calendarまたはjava.util.Dateによって表現されます。ただし、これらのクラスのいずれかを使用せずに、独自のデータ・クラスを実装するとします。例7-1では、単一のユーザー定義のJava値タイプ・クラスoracle.demo.custom_type.MyDateを示します。このクラスはSerializableを実装し、String値を取得および設定するメソッドを含みます。

例7-1 カスタムJava値タイプ・クラスのサンプル

package oracle.demo.custom_type;

public class MyDate implements java.io.Serializable{

    private String string;

    public MyDate(String s) {
        string = s;
    }

    public String getString() {
        return string;
    }

    public void setString(String string) {
        this.string = string;
    }

}

Java値タイプ・クラスのカスタム・シリアライザ実装の定義方法

Webサービス実装でJava値タイプ・クラスを使用し、XMLスキーマ型でWSDLのクラスを表現するには、SOAPElementSerializerの実装を指定する必要があります。実装により、Java値クラス・タイプとXMLスキーマ型の間のシリアライズとデシリアライズが処理されます。

例7-2MyDateSerializerを示します。これは、例7-1に示すMyDate値タイプ・クラスのSOAPElementSerializer実装です。この実装により、Webサービス・エンドポイント・インタフェースでMyDateを使用し、MyDatexsd:dateTime間のシリアライズとデシリアライズを処理できるようになります。また、生成されたWSDLのMyDateクラスを、xsd:dateTimeスキーマ型で表現することも可能になります。

例7-2 SOAPElementSerializerの実装のサンプル

package oracle.demo.custom_type;
import oracle.webservices.databinding.SOAPElementSerializer;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.Text;
import javax.xml.namespace.QName;
import java.util.Iterator;
import java.util.Map;
public class MyDateSerializer implements SOAPElementSerializer {
    private Map initParams;
    protected SOAPFactory soapFactory;
    public MyDateSerializer() {
    }
    public void init(Map prop) {
        initParams = prop;
        try {
            soapFactory = SOAPFactory.newInstance();
        } catch (SOAPException e) {
            e.printStackTrace();
        }
    }
    public Object deserialize(SOAPElement ele) {
        String str = "";
        for( Iterator i = ele.getChildElements(); i.hasNext();) {
            Object obj = i.next();
            if( obj instanceof Text ) {
                str += ( ((Text)obj).getValue() );
            }
        }
    return new MyDate(str);
    }
    /**
    * The qname parameter must be used to create the top level element.
    */
   public SOAPElement serialize(QName qname, Object obj) {
        SOAPElement xml = null;
        try {
            xml = soapFactory.createElement(
            qname.getLocalPart(),
            qname.getPrefix(),
            qname.getNamespaceURI());
            xml.addTextNode( ((MyDate)obj).getString() );
        } catch (SOAPException e) {
            e.printStackTrace();
        }
        return xml;
    }
}

Java値タイプ・クラスを使用するサービス・エンドポイント・インタフェースの定義方法

この項では、ユーザー定義のBeanをWeb Servicesとして使用するJavaサービス・エンドポイント・インタフェースの公開方法を説明します。例7-3および例7-4に、Javaサービス・エンドポイント・インタフェースと、oracle.demo.custom_type.MyDateクラスを使用する実装を示します。例7-5に、インタフェースで使用されるユーザー定義のBeanタイプであるMyDateBeanの定義を示します。

JAX-RPCの要件を満たすために、例7-3MyDateServiceEndpointインタフェースでjava.rmi.Remoteが拡張され、メソッドでjava.rmi.RemoteExceptionがスローされていることに注意してください。

また、インタフェースでは、ユーザー定義のBeanタイプMyDateBeanをパラメータとして使用しています。MyDateBeanには、タイプbeginDateおよびendDateというMyDateの2つのプロパティがあります。MyDateはカスタム・シリアライザを使用するよう構成されており、MyDateBeanはJAX-RPC値タイプ(Bean)パターンに準拠しているため、WebServicesAssemblerによりMyDateBeanのスキーマが生成されます。

例7-3 Javaサービス・エンドポイント・インタフェースのサンプル

package oracle.demo.custom_type;

import oracle.demo.custom_type.MyDate;

public interface MyDateServiceEndpoint extends java.rmi.Remote {

    public MyDate echoMyDate(MyDate date)
            throws java.rmi.RemoteException;


    public MyDateBean echoMyDateBean(MyDateBean bean)
            throws java.rmi.RemoteException;

}

例7-4に、MyDateServiceEndpointの実装を示します。実装に定義されている新しいメソッドで、java.rmi.RemoteExceptionがスローされていることに注意してください。

例7-4 Javaサービス・エンドポイント・インタフェースの実装のサンプル

package oracle.demo.custom_type;

public class MyDateServiceEndpointImpl implements MyDateServiceEndpoint {

    public MyDate echoMyDate(MyDate date) throws java.rmi.RemoteException {
        return date;
    }

    public MyDateBean echoMyDateBean(MyDateBean bean) throws
               java.rmi.RemoteException {
        return bean;
    }

}

例7-5に、インタフェースで使用されるユーザー定義BeanであるMyDateBeanを示します。

例7-5 ユーザー定義のBeanタイプのサンプル

package oracle.demo.custom_type;

public class MyDateBean implements java.io.Serializable{

    private MyDate beginDate;
    private MyDate endDate;

    public MyDate getBeginDate() {
        return beginDate;
    }

    public void setBeginDate(MyDate beginDate) {
        this.beginDate = beginDate;
    }

    public MyDate getEndDate() {
        return endDate;
    }

    public void setEndDate(MyDate endDate) {
        this.endDate = endDate;
    }
}

oracle-webservicesタイプ・マッピング構成の作成方法

oracle-webservicesタイプ・マッピング構成のXMLファイルは、カスタムJava値タイプ・クラスを表現するXMLスキーマ型を指定します。ファイルには、シリアライズするXMLスキーマ型、カスタムJava値タイプ・クラスおよびカスタム・シリアライズを実行するクラスを指定する<type-mapping>が用意されています。表7-1に、<type-mapping>要素のコンテンツを説明します。

表7-1 <type-mapping>要素のコンテンツ

属性または要素名 説明

java-class

type-mapping要素の属性。Java値タイプ・クラスを示します。

serializer-class

type-mapping要素のサブ要素。カスタム・シリアライズを実行するクラスを示します。

xml-type

type-mapping要素の属性。XMLスキーマ型を示します。


スキーマ・ファイルoracle-webservices-10_0.xsdおよびoracle-webservices-types-10_0.xsdは、OC4J_HOME/j2ee/home/lib/ディレクトリのoc4j-schemas.jarファイルにあります。

例7-6に、WebServicesAssemblerにoracle.demo.custom_type.MyDateクラスをxsd:dateTimeにマッピングするよう指示する、oracle-webservicesタイプ・マッピング構成を示します。<serializer-class...>要素は、例7-2で開発したMyDateSerializerクラスを示します。

例7-6 oracle-webservicesタイプ・マッピング構成のサンプル

<oracle-webservices>
    <webservice-description name="MyDateService">
        <type-mappings xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <type-mapping
                java-class="oracle.demo.custom_type.MyDate"
                xml-type="xsd:dateTime">
                <serializer class="oracle.demo.custom_type.MyDateSerializer"/>
            </type-mapping>
        </type-mappings>
    </webservice-description>
</oracle-webservices>

クライアント・プロキシ・コードにおけるカスタム・タイプの使用方法

デフォルトでは、Webサービスのクライアント・プロキシをアセンブルする際には、WebServicesAssemblerはカスタム・タイプを構成しません。アセンブルされたプロキシは、デフォルトのJAX-RPC Java値タイプからXMLスキーマ型へのマッピングを使用します。たとえば、この項に示されているMyDateの例では、xsd:dateTimeを表現するためにデフォルトのJava値タイプjava.util.Calendarが使用されることを意味します。

アセンブルされたクライアント・プロキシ・コードにカスタム・タイプを構成するには、genProxyコマンドにddFileNameおよびclasspath引数を使用します。ddFileName引数では、oracle-webservicesタイプ・マッピング構成のXMLファイルを指定します。classpath引数には、値のタイプおよびカスタム・シリアライザが含まれている必要があります。これにより、クライアント・プロキシ・コードでカスタムJavaクラスを使用できるようになります。

この項の例では、クライアント・プロキシ・コードを生成する際に、oracle-webservicesタイプ・マッピング構成およびそのクラスパスを指定する必要があります。これにより、Web Servicesクライアント・プロキシのxsd:dateTimeMyDateインスタンスを使用できるようになります。

例7-7に、アセンブルされたクライアント・プロキシ・コードを示します。この例では、クライアント・プロキシはxsd:DateTimeへのMyDateのマッピングを設定するoracle-webservicesタイプ・マッピング構成のXMLファイルを使用して生成されたと仮定しています。クライアント・プロキシ・コードでは、デフォルト・マッピングのCalendarではなく、MyDateのインスタンスが使用されていることに注意してください。

例7-7 カスタムJava値タイプを使用するクライアント・サイド・プロキシ・コード

ServiceFactory factory = ServiceFactory.newInstance();
        MyDateService service =  (MyDateService)factory.loadService(MyDateService.class);
        MyDateServiceEndpoint proxy = service.getMyDateServiceEndpointPort();
        ((Stub)proxy)._setProperty( Stub.ENDPOINT_ADDRESS_PROPERTY, address );
        MyDate req = new MyDate("Year:2004, Month:5, Date:24");
        MyDate res = proxy.echoMyDate( req );

        MyDate begin = new java.util.GregorianCalendar(1977, 5, 24);
        MyDate end = new java.util.GregorianCalendar(2004, 5, 24);
        ...

トップダウン方式のWebサービス開発におけるカスタム・シリアライズの使用方法

カスタム・シリアライザを使用して、サービス・エンドポイント・インタフェースのカスタムJava値タイプの、Java値タイプからXMLスキーマ型への特別なマッピングを指定できます。これにより、カスタムJava値タイプを、定義済のタイプであるWSDLのデフォルトのJAX-RPCマッピングに置き換えられます。WebServicesAssemblerにより、カスタムJava値タイプが処理され、インタフェースの適切なコードが生成されます。

たとえば、java.util.Calendarからスキーマ定義のXML型xsd:dateTimeへのデフォルト・マッピングを、カスタムJava値タイプ・クラスMyDateに変更できます。カスタム・シリアライザにより、サービス・エンドポイント・インタフェースに適切なコードを生成できるようになります。

カスタムJava値タイプ・クラス、SOAPElementSerializer実装およびタイプ・マッピング構成ファイルを指定する他に、この点も一般的なトップダウン方式のWebサービスの開発に非常に似ています。

次に示す一般的な手順に従って、カスタム・シリアライザを使用するWebサービスを開発します。

  1. WebServicesAssemblerのgenInterfaceコマンドおよびカスタム・シリアライザを実行して、カスタム・タイプ・マッピングを持つサービス・エンドポイント・インタフェースを生成します。

  2. サービス・エンドポイント・インタフェースを実装します。

  3. WebServicesAssemblerのtopdownAssembleコマンドを再度実行し、WebサービスをアセンブルしてEARにパッケージ化します。

次の項では、これらの手順をさらに詳細に説明します。

前提条件

開始する前に、次のファイルと情報を用意してください。

トップダウン方式のWebサービス開発におけるカスタム・シリアライズの使用手順

次の手順では、トップダウン方式でのWebサービス開発にカスタム・シリアライズを使用する方法を説明します。

  1. 前提条件のセクションで説明されているファイルを、WebServicesAssemblerのgenInterfaceコマンドへの入力として指定します。次に例を示します。

    java -jar wsa.jar -genInterface
                     -ddFileName myOracleWSDescriptor.xml
                     -output build/src/service
                     -wsdl wsdl/MyWSDL.wsdl
                     -unwrapParameters false
                     -packageName oracle.demo.customdoclit.service
    

    次に、このコマンドを説明します。

    • genInterface: 各ポート・タイプおよびWSDLに定義されているいずれかの複合型のJava値タイプ・クラス(Bean)のサービス・エンドポイントを作成します。XMLスキーマ型とJava値タイプ・クラス間のマッピングを設定するJAX-RPCマッピング・ファイルを作成します。

    • ddFileName: Web Servicesに割り当てる設定を含むoracle-webservices.xmlデプロイメント・ディスクリプタを指定します。

    • output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。

    • wsdl: WSDLドキュメントへの絶対ファイル・パス、相対ファイル・パスまたはURLを指定します。

    • unwrapParameters: この引数は、document-literal操作にのみ設定され、それ以外のメッセージ書式では無視されます。falseに設定されると、生成されたサービス・エンドポイント・インタフェースは、入力パラメータおよび戻り型に対するラッパーを使用して生成されます。

    • packageName: JAX-RPCマッピング・ファイルでパッケージ名が宣言されていない場合、生成されたクラスで使用するパッケージ名を指定します。


    関連資料:

    これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。


    カスタム・シリアライザを使用する場合と標準のトップダウン方式でWebサービスを開発する場合の主な違いは、ddFileName引数の存在です。myOracleWSDescriptor.xmlファイルには、WebServicesAssemblerおよびWebServicesAssemblerがサービス・エンドポイント・インタフェースの生成に使用するマッピングが用意されています。

    また、WebServicesAssemblerは、このファイルのカスタム・マッピングを使用して、WSDLに指定されているポート・タイプごとのJavaインタフェースおよび複合タイプごとのJavaBeanを生成します。

    生成されたインタフェースが格納されるディレクトリの名前は、outputおよびpackageName引数の値に基づいて付けられます。この例の場合、生成されたインタフェースはbuild/src/service/oracle/demo/customdoclit/serviceに格納されます。

  2. 生成されたインタフェースおよびタイプ・クラスをコンパイルします。

    次に例を示します。

    javac -destdir ${service.classes.dir}
          -excludes {javac.excludes}
          -path build/src/service
          -classpath ${wsdemo.common.class.path}
    

    『Oracle Application Server Web Services開発者ガイド』の「Webサービス・クライアントのAPIおよびJAR」で説明されている、参照されたライブラリを含むようにCLASSPATHを設定した場合は、classpath引数を省略できます。それ以外の場合は、${wsdemo.common.class.path}で表されているパスにこれらのライブラリがすべて含まれていることを確認してください。Antの例を実行している場合、Antビルド・スクリプトを適切に設定してください。

  3. サービス・エンドポイント・インタフェースを実装します。

    実装には、生成されたJavaインタフェース内のすべてのメソッドと一致するメソッド・シグネチャが必要です。

  4. サービス実装をコンパイルします。

    たとえば、Implクラスが保存されているディレクトリと同じディレクトリでインタフェースのソースが生成された場合は、手順2と同じコマンドを使用できます。そうでない場合は、path引数の値を変更する必要があります。

  5. サービス・エンドポイント実装、WSDL、カスタムJava値タイプ・クラス、SOAPElementSerializer実装およびタイプ・マッピング構成のXMLファイルを、WebServicesAssemblerのtopdownAssembleコマンドの入力として指定します。このコマンドにより、デプロイ可能なEARファイルが生成されてパッケージ化されます。

    java -jar wsa.jar - topDownAssemble
                      -ddFileName myOracleWSDescriptor.xml
                      -output ./build
                      -wsdl wsdl/MyWSDL.wsdl
                      -unwrapParameters false
                      -packageName oracle.demo.customdoclit.service
                      -className oracle.demo.customdoclit.service.MyEndpointImpl
                      -appName MyWebService
                      -ear ./build/MyWebService.ear
    

    次に、このコマンドおよびAntタスクを説明します。

    • topDownAssemble: 必要なクラスおよびWSDLの説明に基づいたWebサービスのデプロイメント・ディスクリプタを作成します。このファイルはEARファイル、WARファイルまたはディレクトリのいずれかに保存されます。

    • ddFileName: Web Servicesに割り当てる設定を含むoracle-webservices.xmlデプロイメント・ディスクリプタを指定します。

    • output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。

    • wsdl: WSDLドキュメントへの絶対ファイル・パス、相対ファイル・パスまたはURLを指定します。

    • unwrapParameters: falseに設定されると、生成されたサービス・エンドポイント・インタフェースは、入力パラメータおよび戻り型に対するラッパーを使用して生成されます。

    • packageName: JAX-RPCマッピング・ファイルでパッケージ名が宣言されていない場合、生成されたクラスで使用するパッケージ名を指定します。

    • className: Webサービスの実装クラスであるクラス名(パッケージ名を含みます)を指定します。

    • appName: アプリケーション名を指定します。通常、この名前はcontextおよびuriなどの他の引数のベース値として使用されます。

    • ear: 生成されたEARの名前および場所を指定します。


    関連資料:

    これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。


  6. WebServicesAssemblerを使用して、次のいずれかの方法でWebサービスのクライアント・サイド・プロキシを生成します。

    • WebServicesAssemblerツールのgenProxyコマンドを実行して、J2SE Webサービス・クライアントのスタブ(クライアント・プロキシ)を生成します。

    • WebServicesAssemblerツールのgenInterfaceコマンドを実行して、サービス・エンドポイント・インタフェースおよびJ2EE Webサービス・クライアント用のJAX-RPCマッピング・ファイルを生成します。

      クライアント・サイド・コードのアセンブルの詳細は、『Oracle Application Server Web Services開発者ガイド』の「J2EE Webサービス・クライアントのアセンブル」および「J2SE Webサービス・クライアントのアセンブル」で説明されています。

    クライアント・サイド・プロキシ・コードでxsd:dateTimeを表すためにMyDateを使用するには、ddFileNameを使用してoracle-webservicesタイプ・マッピング構成のXMLファイルを指定し、classpathを使用してカスタムJavaクラスMyDateへのパスを指定する必要があります。

    たとえば、次のコマンドは、J2SEクライアント用に使用可能なクライアント・プロキシ(スタブ)を生成します。

    java -jar wsa.jar -genProxy
        -wsdl http://localhost:8888/custom_type_mydate/custom_type_mydate?WSDL
        -packageName oracle.demo.custom_type.mydate_with_ser
        -output ./build/src/client
        -ddFileName MyClientSideDD.xml
        -classpath ./build/classes/service
    

    次に、このコマンドおよびAntタスクを説明します。

    • genProxy: J2SE Webサービス・クライアントで使用できる静的プロキシ・スタブを作成します。

    • wsdl: WSDLドキュメントへの絶対ファイル・パス、相対ファイル・パスまたはURLを指定します。

    • packageName: JAX-RPCマッピング・ファイルでパッケージ名が宣言されていない場合、生成されたクラスで使用するパッケージ名を指定します。

    • output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。

    • ddFileName: Web Servicesに割り当てる設定を含むoracle-webservices.xmlデプロイメント・ディスクリプタを指定します。

    • classpath: WebServicesAssemblerに指定されるすべてのユーザー作成クラスを含むクラスパスを指定します。作成済の値タイプ・クラスまたは例外があり、WebServicesAssemblerで上書きしたくない場合に、この引数を指定します。


    関連資料:


ボトムアップ方式のWebサービス開発におけるカスタム・シリアライズの使用方法

カスタム・シリアライザを使用して、サービス・エンドポイント・インタフェースで使用される特定のJava値タイプの、Java値タイプからXMLスキーマ型への特別なマッピングを指定できます。これは、Java値タイプからXMLスキーマ型への特別なマッピングを説明する独自のカスタム・スキーマ・ドキュメントを使用できることを意味します。Java値タイプからXMLスキーマ型への特別なマッピングを指定した場合は、WebServicesAssemblerでこれらのタイプのスキーマ定義を生成する必要はありません。

ボトムアップ方式でのWebサービスの開発であるため、WebServicesAssemblerによりWSDLが生成されます。WSDLでは、値のタイプにスキーマを生成するかわりに、WebServicesAssemblerにより指定する1つ以上のスキーマ・ドキュメントがインポートされます。

前提条件

開始する前に、次のファイルと情報を用意してください。

ボトムアップ方式のWebサービス開発におけるカスタム・シリアライズの使用手順

次の説明では、カスタム・タイプ・マッピングを必要とする、ボトムアップ方式でのWebサービスをアセンブルします。

  1. 前提条件のセクションで説明されているファイルを、WebServicesAssemblerのassembleコマンドへの入力として指定します。

    このコマンドは、oracle-webservicesタイプ・マッピング構成のXMLファイルの指定にddFileName引数が使用されていること以外は、標準のボトムアップ方式によるWebサービス開発と似ています。input引数には、カスタム・シリアライザの実装が含まれています。WebServicesAssemblerにより、WSDLが生成され、デプロイ可能なEARファイルがパッケージ化されます。

    コマンドライン

    java -jar wsa.jar -assemble
        -targetNamespace http://oracle.com/ws_demo/custom_type_mydate
        -typeNamespace http://oracle.com/ws_demo/custom_type_mydate
        -input ./build/classes/service
        -classpath ./build/classes/service
        -output ./dist
        -ddFileName ./MyOracleWSDescriptor.xml
        -interfaceName oracle.demo.custom_type.MyDateServiceEndpoint
        -className oracle.demo.custom_type.MyDateServiceEndpointImpl
        -serviceName MyDateService
        -appName custom_type_mydate
    

    Antタスク

    <oracle:assemble targetNamespace="http://oracle.com/ws_demo/custom_type_mydate"
        typeNamespace="http://oracle.com/ws_demo/custom_type_mydate"
        input="./build/classes/service"
        classpath="./build/classes/service"
        output="./dist"
        ddFileName="./custom_type_mydate_pdd.xml"
        serviceName="MyDateService"
        appName="custom_type_mydate"
        >
            <oracle:porttype
                interfaceName="oracle.demo.custom_type.MyDateServiceEndpoint"
                className="oracle.demo.custom_type.MyDateServiceEndpointImpl">
            </oracle:porttype>
    </oracle:assemble>
    

    次に、このコマンドおよびAntタスクを説明します。

    • assemble: Javaファイルを使用したボトムアップ方式のWebサービスを生成します。このコマンドで、デプロイ可能なアーカイブの作成に必要とされるすべてのファイルを作成します。

    • targetNamespace: 生成されたWSDLで使用するターゲット名前空間を指定します。この値には、準拠HTTP URL、非準拠HTTP URLまたはURIのいずれかの値が可能です。

    • typeNamespace: 生成されたWSDLのスキーマ型で使用するタイプ名前空間を指定します。指定した名前が常に使用され、逆向きになることはありません。

    • input: WEB-INF/classesにコピーする必要があるクラスを含むディレクトリまたはJARを指定します。この引数は、WebServicesAssemblerで使用するクラスパスに追加されます。

    • classpath: WebServicesAssemblerに指定されるすべてのユーザー作成クラスを含むクラスパスを指定します。作成済の値タイプ・クラスまたは例外があり、WebServicesAssemblerで上書きしたくない場合に、この引数を指定します。

    • output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。

    • ddFileName: Web Servicesに割り当てる設定を含むoracle-webservices.xmlデプロイメント・ディスクリプタを指定します。

    • interfaceName: サービス・エンドポイント・インタフェース(SEI)を含むJavaクラス名(パッケージ名を含みます)を指定します。

    • className: Webサービスの実装クラスであるクラス名(パッケージ名を含みます)を指定します。

    • serviceName: サービス名を指定します。

    • appName: アプリケーション名を指定します。通常、この名前はcontextおよびuriなどの他の引数のベース値として使用されます。


    関連資料:

    これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。


  2. WebServicesAssemblerを使用して、Webサービスのクライアント・サイド・プロキシを生成します。クライアント・サイド・プロキシ・コードでxsd:dateTimeを表すためにMyDateを使用するには、ddFileNameを使用してoracle-webservicesタイプ・マッピング構成ファイルを指定し、classpathを使用してカスタムJavaクラスMyDateへのパスを指定する必要があります。

    コマンドライン

    java -jar wsa.jar -genProxy
        -wsdl http://localhost:8888/custom_type_mydate/custom_type_mydate?WSDL
        -packageName oracle.demo.custom_type.mydate_with_ser
        -output ./build/src/client
        -ddFileName ./MyClientSideDD.xml
        -classpath ./build/classes/service
    

    Antタスク

    <oracle:genProxy
              wsdl="http://localhost:8888/custom_type_mydate/custom_type_mydate?WSDL"
              packageName="oracle.demo.custom_type.mydate_with_ser"
              output="./build/src/client"
              ddFileName="./MyOracleClientDD.xml"
              classpath="./build/classes/client"
               />
    

    次に、このコマンドおよびAntタスクを説明します。

    • genProxy: J2SE Webサービス・クライアントで使用できる静的プロキシ・スタブを作成します。

    • wsdl: WSDLドキュメントへの絶対ファイル・パス、相対ファイル・パスまたはURLを指定します。

    • packageName: JAX-RPCマッピング・ファイルでパッケージ名が宣言されていない場合、生成されたクラスで使用するパッケージ名を指定します。

    • output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。

    • ddFileName: Web Servicesに割り当てる設定を含むoracle-webservices.xmlデプロイメント・ディスクリプタを指定します。

    • classpath: WebServicesAssemblerに指定されるすべてのユーザー作成クラスを含むクラスパスを指定します。作成済の値タイプ・クラスまたは例外があり、WebServicesAssemblerで上書きしたくない場合に、この引数を指定します。


    関連資料:


スキーマ・ドリブン方式のWebサービス開発におけるカスタム・シリアライズの使用方法

スキーマ・ドリブン方式のWebサービス開発では、スキーマ・ドキュメントを使用してWebServicesAssemblerを起動し、Webサービスをアセンブルする前にJava値タイプ・クラス(Bean)を生成します。

スキーマの複合型から生成されたJava値クラスは、JAX-RPC値タイプ(Bean)パターンの要件に準拠しているため、カスタム・シリアライザは不要です。JAX-RPCにより提供されているデフォルト・マッピングで問題ない場合は、カスタム・シリアライザを実装する必要はありません。

ただし、XMLとJava間のデフォルトのマーシャリングを変更する必要がある場合は、生成されるJava値タイプ・クラス用にカスタム・シリアライザを実装する必要があります。

次に示す一般的な手順に従って、スキーマからWebサービスをアセンブルします。

  1. スキーマ・ドキュメントを使用してWebServicesAssemblerを実行し、Java値タイプ・クラス、標準のJAX-RPCマッピング・ファイル、およびoracle-webservicesタイプ・マッピング構成のXMLファイル(custom-type-mappings.xml)を生成します。

  2. 独自のサービス・エンドポイント・インタフェースとその実装を開発します。ここでは、インタフェースおよび実装が、手順1のスキーマ・ドキュメントで使用されていないカスタムJavaデータ型を1つ以上使用すると仮定しています。

  3. デフォルトのマーシャリングが1つ以上のクラスで不十分な場合は、カスタム・シリアライザを作成して独自のマーシャリング・ロジックを実装します。

  4. oracle-webservicesタイプ・マッピング構成のXMLファイルを編集し、カスタム・シリアライザを含めます。また、代替のJavaクラスを生成された任意のJava値タイプ・クラスに置き換えることも可能です。

  5. WebServicesAssemblerを再度実行し、今度はWSDLドキュメントを生成します。JAX-RPCマッピング・ファイル、編集されたoracle-webservicesタイプ・マッピング構成のXMLファイル、スキーマ・ドキュメント、生成されたJava値タイプ、およびサービス・エンドポイント・インタフェースとその実装を入力します。また、作成した場合は、カスタム・シリアライザも含めます。

    Java値タイプから生成するのではなく、生成されたWSDLにより、指定したスキーマがインポートされます。

WebServicesAssemblerにより、生成されたWSDL、およびすべての実装ファイルとデプロイメント・ディスクリプタがデプロイ可能なEARとアセンブルされ、Webサービスが有効化されます。

前提条件

開始する前に、次のファイルと情報を用意してください。

  • スキーマ・ドキュメント。

    Java値タイプ・クラスを生成するスキーマ・ドキュメントの例は、「スキーマ・ドキュメントのサンプル」を参照してください。

  • サービス・エンドポイント・インタフェースとその実装。

    ここでは、インタフェースおよび実装が、スキーマ・ドキュメントで使用されていないカスタムJavaデータ型を1つ以上使用すると仮定しています。サービス・エンドポイント・インタフェースのサンプルおよび手順1で説明したスキーマ・ドキュメントに表示されないカスタムJavaデータ型を使用する実装は、「サービス・エンドポイント・インタフェースおよび実装のサンプル」を参照してください。

  • スキーマの複合型を表すJavaカスタム型の定義。

    サンプル・インタフェースおよび実装で使用したJavaカスタム・データ型の実装は、「Javaカスタム型の実装」を参照してください。

  • カスタムのデフォルト・マーシャリング・ロジックを指定している場合には、カスタム・シリアライザも作成して独自のマーシャリング・ロジックを実装する必要があります。

    シリアライザおよびマーシャリング・ロジックの実装方法は、「カスタム・マーシャリング・ロジックを使用したシリアライザの実装方法」で説明されています。


関連資料:

サービス・エンドポイント・インタフェースを介して公開できるタイプを定義するスキーマ・ドキュメントの詳細は、「スキーマ・ドキュメントのサンプル」を参照してください。


カスタム・シリアライズを使用したスキーマ・ドリブン方式のWebサービス・アセンブリ手順

この章では、複合型を含むXMLスキーマからWebサービスを開発する方法を説明します。また、カスタム・シリアライザを作成して、複合型とJavaカスタム型の間のシリアライズおよびデシリアライズを処理する方法も説明します。「スキーマ・ドキュメントのサンプル」には、この例で使用されるスキーマが説明されています。スキーマには、InitItemおよびStringItemの2つの複合型があります。

この項では、「Javaカスタム型の実装のサンプル」で説明されているJava型oracle.webservices.examples.customtypes.MyInitItemを使用し、スキーマのInitItem複合型を表すことを仮定しています。これを実行するには、カスタム・シリアライザを作成して、MyInitItemのJavaインスタンスとInitItemのXMLインスタンスのシリアライズおよびデシリアライズを処理する必要があります。

複合スキーマ型StringItemの場合、この項ではデフォルトのJAX-RPC値タイプのデータ・バインディング・メカニズムを使用して値タイプ・クラスを生成し、複合型を表すことを仮定しています。また、xsd:stringのXMLインスタンスでカスタム書式設定を行うことも仮定しています。これを実行するために、カスタム・シリアライザが作成され、java.lang.StringのJavaインスタンスとxsd:stringのXMLインスタンスの間のシリアライズおよびデシリアライズが処理されます。

次の手順では、このWebサービスを開発する方法を説明します。

  1. スキーマ・ドキュメントを使用してWebServicesAssemblerを実行し、Java値タイプおよび標準のJAX-RPCマッピング・ファイルを生成します。

    java -jar wsa.jar -genValueTypes
                      -packageName oracle.webservices.examples.customtypes
                      -schema ./MySchema.xsd
                      -output ./build/src/types
    

    次に、このコマンドを説明します。

    • genValueTypes: 指定されたスキーマからJAX-RPC値タイプ・クラス(Bean)を作成します。

    • packageName: JAX-RPCマッピング・ファイルでパッケージ名が宣言されていない場合、生成されたクラスで使用するパッケージ名を指定します。

    • schema: XMLスキーマ・ドキュメントへの相対パスまたはURLを指定します。この引数により、WebServicesAssemblerで生成せずに、値タイプのスキーマを指定できます。

    • output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。


    関連資料:

    これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。


    このコマンドで使用されるスキーマ・ドキュメントは、「スキーマ・ドキュメントのサンプル」で説明されています。genValueTypesコマンドはこのスキーマから、InitItemおよびStringItemの2つのクラスを生成します。カスタム・タイプ・クラスと置き換えるため、InitItemクラスは不要です。

    このコマンドは、生成された値タイプ・クラスのバインディングを説明するJAX-RPCマッピング・ファイルjaxrpc-mappings.xml、および既存のスキーマ・ファイルからどの値タイプ・クラスが生成されたかを記録するためのcustom-type-mappings.xmlファイルも生成します。custom-type-mappings.xmlファイルは、OracleAS Web Servicesタイプ・マッピング構成のXMLファイル用に生成されたサーバー・サイド・インスタンスです。

  2. 生成された値タイプを/build/classes/serviceディレクトリにコンパイルします。

    genValueTypesコマンドはクラスをコンパイルしません。この手順は手動で実行する必要があります。IntItemクラスを削除することも、コンパイルから除外することもできます。これは、このクラスにカスタム・シリアライザを指定するためです。

  3. カスタム・シリアライザを実装します。この例では、oracle.webservices.examples.customtypes.MyIntItemInitItemをマッピングするシリアライザ、およびjava.lang.Stringxsd:stringをマッピングするシリアライザの2つのカスタム・シリアライザが必要です。

    これらのシリアライザの実装のサンプルは、「マーシャリング・ロジックを使用したシリアライザ実装の定義」で説明されています。

  4. サービス・エンドポイント・インタフェースとその実装を開発します。

    oracle.webservices.examples.customtypes.MyInitItemおよび生成されたJava値タイプ・クラスを使用する、サービス・エンドポイント・インタフェースの実装のサンプルは、「サービス・エンドポイント・インタフェースおよび実装のサンプル」で説明されています。

  5. custom-type-mappings.xmlファイルを編集し、代替のJavaクラスとカスタム・シリアライザを含めます。手順1で、custom-type-mappings.xmlファイルは出力ディレクトリ/build/src/typesに生成されました。

    oracle.webservices.examples.customtypes.MyInitItemとそのカスタム・シリアライザ、およびoracle.webservices.examples.customtypes.MyStringSerializerカスタム・シリアライザを使用するようファイルを編集します。

    代替のJavaクラスおよびカスタム・シリアライザを追加する詳細は、「Java値タイプ・クラスのタイプ・マッピング構成のXMLファイルの編集方法」で説明されています。

  6. 今度はWebServicesAssemblerツールのassembleコマンドを実行し、WSDLおよびデプロイ可能なEARファイルを生成します。次の項目を入力として使用します。

    • schema引数のターゲットとしてのXMLスキーマ・ドキュメント(MySchema.xsd)。

    • 手順1で生成された値タイプ・クラス。このクラスはinput引数で指定するディレクトリ(build/classes.service)に保存されます。

    • 手順1で生成されたJAX-RPCマッピング・ファイル(jaxrpc-mappings.xml)。

    • 手順2で作成されたコンパイル済シリアライザ・クラス。このクラスはinput引数で指定するディレクトリ(build/classes.service)に保存されます。

    • 手順3で作成されたサービス・エンドポイント・インタフェースMyEndpointIntfおよびその実装MyEndpointImpl。このファイルはinterfaceNameおよびclassName引数のターゲットです。

    • 手順4で作成された、変更済のカスタム・タイプ・マッピング・ファイルMyCustomTypeMappings.xml。このファイルには、各カスタム・シリアライザのクラス名がリストされています。このファイルを、ddFileName引数のターゲットとして入力します。

    • appName引数は、生成されたアプリケーション名を示します。

    WebServicesAssemblerツールにより、/distディレクトリのデプロイ可能なEARファイルがアセンブルされます。EARファイルの生成されたWSDLにより、スキーマ・ドキュメントがインポートされます。次のassembleコマンドは、通常のJavaからWSDLへのアセンブリ、またはボトムアップ方式のWebサービス・アセンブリに似ていることに注意してください。

    java -jar wsa.jar -assemble
              -schema ./MySchema.xsd
              -mappingFileName ./build/src/types/jaxrpc-mappings.xml
              -input ./build/classes/service
              -classpath ./build/classes/service
              -output ./dist
              -ddFileName ./MyCustomTypeMappings.xml
              -interfaceName oracle.webservices.examples.customtypes.MyEndpointIntf
              -className oracle.webservices.examples.customtypes.MyEndpointImpl
              -appName MyCustomTypes
    

    次に、このコマンドを説明します。

    • assemble: Javaファイルを使用したボトムアップ方式のWebサービスを生成します。このコマンドで、デプロイ可能なアーカイブの作成に必要とされるすべてのファイルを作成します。

    • schema: XMLスキーマ・ドキュメントへの相対パスまたはURLを指定します。この引数により、WebServicesAssemblerで生成せずに、値タイプのスキーマを指定できます。

    • mappingFileName: JAX-RPCマッピング・ファイルを示すファイルの場所を指定します。

    • input: WEB-INF/classesにコピーする必要があるクラスを含むディレクトリまたはJARを指定します。この引数は、WebServicesAssemblerで使用するクラスパスに追加されます。

    • classpath: WebServicesAssemblerに指定されるすべてのユーザー作成クラスを含むクラスパスを指定します。作成済の値タイプ・クラスまたは例外があり、WebServicesAssemblerで上書きしたくない場合に、この引数を指定します。

    • output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。

    • ddFileName: Web Servicesに割り当てる設定を含むoracle-webservices.xmlデプロイメント・ディスクリプタを指定します。

    • interfaceName: サービス・エンドポイント・インタフェース(SEI)を含むJavaクラス名(パッケージ名を含みます)を指定します。

    • className: Webサービスの実装クラスであるクラス名(パッケージ名を含みます)を指定します。

    • appName: アプリケーション名を指定します。通常、この名前はcontextおよびuriなどの他の引数のベース値として使用されます。


    関連資料:

    これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。


  7. サービスをデプロイし、アプリケーションをバインドします。

    通常の方法でEARファイルをOC4Jの実行中インスタンスにデプロイします。次は、デプロイメント・コマンドのサンプルです。

    java -jar <OC4J_HOME>/j2ee/home/admin_client.jar deployer:oc4j:localhost:port <user> <password>
                 -deploy
                 -file ./dist/MyCustomTypes.ear
                 -deploymentName MyCustomTypes
                 -bindWebApp default-web-site
    

    EARファイルのデプロイの詳細は、『Oracle Containers for J2EEデプロイメント・ガイド』で説明されています。

  8. 次のいずれかの方法でクライアントを開発します。

    • WebServicesAssemblerツールのgenProxyコマンドを実行して、J2SE Webサービス・クライアントのスタブ(クライアント・プロキシ)を生成します。

    • WebServicesAssemblerツールのgenInterfaceコマンドを実行して、サービス・エンドポイント・インタフェースおよびJ2EE Webサービス・クライアント用のJAX-RPCマッピング・ファイルを生成します。

    InitItemを表す際にoracle.webservices.examples.customtypes.MyInitItemを使用し、クライアントとサーバー間のデータのマーシャリングおよびアンマーシャリングにカスタム・シリアライザを使用するJ2SEクライアント・サイド・プロキシを開発する例は、「カスタム・タイプ・マッピングおよびカスタム・シリアライザのクライアントのアセンブル方法」で説明されています。

スキーマ・ドキュメントのサンプル

例7-8に、サービス・エンドポイント・インタフェースとして公開されるタイプを指定するMySchema.xsdスキーマ・ドキュメントを示します。InitItemおよびStringItemは複合型です。

例7-8 InitItemおよびStringItemのスキーマ定義

<?xml version = '1.0' encoding = 'UTF-8'?>
<schema
   targetNamespace="http://examples.webservices.oracle/customtypes"
   xmlns:tns="http://ws.oracle.com/types"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns="http://www.w3.org/2001/XMLSchema">

   <complexType name="IntItem">
      <sequence>
         <element name="name" type="xsd:string"/>
         <element name="value" type="xsd:int"/>
      </sequence>
   </complexType>

   <complexType name="StringItem">
      <sequence>
         <element name="name" type="xsd:string"/>
         <element name="value" type="xsd:string"/>
      </sequence>
   </complexType>
</schema>

サービス・エンドポイント・インタフェースおよび実装のサンプル

この項では、スキーマ・ドキュメントとは異なるJavaデータ型を使用するサービス・エンドポイント実装を説明します。

例7-10に、サンプルのサービス・エンドポイント・インタフェースoracle.webservices.examples.customtypes.MyEndpointIntfを、例7-11にその実装oracle.webservices.examples.customtypes.MyEndpointImplを示します。インタフェースではjava.rmi.Remoteを拡張し、そのメソッドはjava.rmi.RemoteExceptionをスローしていることに注意してください。また、インタフェースおよび実装のgetItemsメソッドは、スキーマ・ドキュメントから生成されたInitItem値タイプ・クラスではなくタイプMyInitItemを取得していることに注意してください。

oracle.webservices.examples.customtypes.MyInitItemデータ型を使用するメソッドを公開するWebサービスをアセンブルするには、oracle-webservicesタイプ・マッピング構成のXMLファイルのInitItemエントリをMyInitItemに置き換える必要もあります。

オプションで、MyInitItemデータのカスタムのマーシャリングおよびアンマーシャリングを指定する場合には、このクラスにカスタム・シリアライザを実装する必要があります。


関連資料:


例7-9に、Itemsカスタム・タイプ・クラスの定義を示します。このクラスは、サービス・エンドポイント実装で使用されます。Itemクラスでは、MyIntItemおよびStringItemの2つの値タイプを使用します。MyInitItemクラスは、カスタム・シリアライザを指定する必要のあるカスタム・クラスです。StringItemクラスは、Stringのカスタム・マッピングを使用してスキーマから生成されます。MyIntItemおよびStringItemの両方とも、既存のスキーマ・ドキュメントで説明されています。

例7-9 Itemsクラスの定義

package oracle.webservices.examples.customtypes;

public class Items {
    private MyIntItem[]  myIntItem;
    private StringItem[] stringItem;
    public Items() {
    }
    public Items(MyIntItem[] intItem, StringItem[] strItem) {
        myIntItem  = intItem;
        stringItem = strItem;
    }
    public MyIntItem[] getMyIntItem() {
        return myIntItem;
    }
    public void setMyIntItem(MyIntItem[] intItem) {
        myIntItem = intItem;
    }
    public StringItem[] getStringItem() {
        return stringItem;
    }
    public void setStringItem(StringItem[] strItem) {
        stringItem = strItem;
    }
}

例7-10に、MyEndpointIntfのサービス・エンドポイント・インタフェースを示します。getItemsメソッドでは、スキーマで定義されたInitItem型ではなくMyInitItemデータ型が使用されています。JAX-RPCで要求されているように、インタフェースでjava.rmi.Remoteを拡張し、メソッドではjava.rmi.RemoteExceptionをスローしています。

例7-10 MyEndpointIntfのサービス・エンドポイント・インタフェース

package oracle.webservices.examples.customtypes;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface MyEndpointIntf extends Remote {
    public Items getItems( MyIntItem[] myInts, StringItem[] myStrings )
        throws RemoteException;
}

例7-11に、MyEndpointIntfインタフェースの実装を示します。

例7-11 サービス・エンドポイントの実装

package oracle.webservices.examples.customtypes;

public class MyEndpointImpl {

    public Items getItems( MyIntItem[] myInts, StringItem[] myStrings ) {
        Items items = new Items();
        items.setMyIntItem(myInts);
        items.setStringItem(myStrings);
        return items;
    }
}

Javaカスタム型の実装のサンプル

例7-12に、Javaカスタム型oracle.webservices.examples.customtypes.MyIntItemの実装を示します。このタイプは、例7-8に示されているスキーマで使用するInitItem複合型を表す際に使用されます。

例7-12 Javaカスタム型InitItemの実装

/**
 * MyIntItem does not have the JAXRPC Value type (Bean) pattern.
 */
package oracle.webservices.examples.customtypes;
public class MyIntItem {
    private String name;
    private int value;
    public MyIntItem(String name, int value) {
        this.name = name;
        this.value = value;
    }
    public String itemName() {
        return name;
    }
    public int itemValue() {
        return value;
    }
}

カスタム・マーシャリング・ロジックを使用したシリアライザの実装方法

この項では、カスタムのマーシャリングおよびアンマーシャリング・ロジックを含むシリアライザ実装の例を示します。スキーマ・ドキュメントのInitItem複合型を表すために、Webサービスでoracle.webservices.examples.customtypes.MyInitItemカスタムJavaデータ型を使用することを仮定しています。また、クラスにカスタムのマーシャリングおよびアンマーシャリング・ロジックを指定することも仮定しています。カスタム・ロジックを指定するには、カスタム・シリアライザを実装する必要があります。

例7-13に、MyInitItemのカスタム・シリアライザ実装のサンプルを示します。シリアライズ機能を指定するために、カスタム・シリアライザMyInitItemSerializerSOAPElementSerializerクラス、およびそのserializedeserializeメソッドを実装しています。

例7-13 MyInitItemをInitItemにマッピングするためのカスタム・シリアライザ実装

package oracle.webservices.examples.customtypes;

import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.Text;

import oracle.webservices.databinding.SOAPElementSerializer;

public class MyIntItemSerializer implements SOAPElementSerializer {

    private Map config;
    private SOAPFactory soapFactory;
    public void init(Map initParams) {
        config = initParams;
        try {
            soapFactory = SOAPFactory.newInstance();
        } catch (SOAPException e) {
            e.printStackTrace();
        }
    }

    public SOAPElement serialize(QName tagName, Object object) {
        MyIntItem myIntItem = (MyIntItem)object;
        SOAPElement xml = null;
        try {
            xml = soapFactory.createElement(
                  tagName.getLocalPart(), tagName.getPrefix(), tagName.getNamespaceURI());

            SOAPElement name = soapFactory.createElement(
                  "name", tagName.getPrefix(), tagName.getNamespaceURI());
            name.addTextNode(myIntItem.itemName());

            SOAPElement value = soapFactory.createElement(
                  "value", tagName.getPrefix(), tagName.getNamespaceURI());
            value.addTextNode(String.valueOf(myIntItem.itemValue()));

            xml.addChildElement(name);
            xml.addChildElement(value);
        } catch (SOAPException e) {
            e.printStackTrace();
        }
        return xml;
    }

    private String getTextContent(SOAPElement element) {
        String str = "";
        for (Iterator i = element.getChildElements(); i.hasNext();) {
            Object obj = i.next();
            if (obj instanceof Text) {
                str += (((Text) obj).getValue());
            }
        }
        return str;
    }

    public Object deserialize(SOAPElement element) {
        String name = null;
        int value = -1;
        for (Iterator i = element.getChildElements(); i.hasNext();) {
            Object obj = i.next();
            if (obj instanceof SOAPElement) {
                SOAPElement child = (SOAPElement)obj;
                if (child.getLocalName().equals("name")) {
                    name = MyStringSerializer.createMyString(getTextContent(child));
                }
                if (child.getLocalName().equals("value")) {
                    value = Integer.parseInt(getTextContent(child));
                }
            }
        }
        return new MyIntItem(name, value);
    }
}

例7-14に、java.lang.Stringxsd:stringにマッピングするためのカスタム・シリアライズ実装のサンプルを示します。シリアライズ機能を指定するために、カスタム・シリアライザMyStringSerializerSOAPElementSerializerクラス、およびそのserializedeserializeメソッドを実装しています。また、独自の文字列書式や検証コードを入力できるプレースホルダも指定しています。

例7-14 java.lang.Stringをxsd:stringにマッピングするためのカスタム・シリアライザ実装

package oracle.webservices.examples.customtypes;

import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.Text;

import oracle.webservices.databinding.SOAPElementSerializer;

public class MyStringSerializer implements SOAPElementSerializer {

    private Map config;
    private SOAPFactory soapFactory;

    public void init(Map initParams) {
        config = initParams;
        try {
            soapFactory = SOAPFactory.newInstance();
        } catch (SOAPException e) {
            e.printStackTrace();
        }
    }

    public SOAPElement serialize(QName tagName, Object object) {
        String value = (object == null) ? "null" : object.toString();
        SOAPElement xml = null;
        try {
            xml = soapFactory.createElement( tagName.getLocalPart(),
                                             tagName.getPrefix(),
                                             tagName.getNamespaceURI());
            xml.addTextNode(value);
        } catch (SOAPException e) {
            e.printStackTrace();
        }
        return xml;
    }

    public Object deserialize(SOAPElement element) {
        String value = "";
        for (Iterator i = element.getChildElements(); i.hasNext();) {
            Object obj = i.next();
            if (obj instanceof Text) {
                value += (((Text) obj).getValue());
            }
        }
        return createMyString( value );
    }

    static public String createMyString(String input) {
        // You can add your own formating or validation logic here
        return input.trim().toUpperCase();
    }
}

Java値タイプ・クラスのタイプ・マッピング構成のXMLファイルの編集方法

genValueTypesコマンドにより、生成されたoracle-webservicesタイプ・マッピング構成のXMLファイルcustom-type-mappings.xmlのインスタンスが作成されます。このファイルは、既存のスキーマ・ドキュメントから生成されたJava値タイプ・クラスを記録します。サービス・エンドポイント・インタフェースからWSDLを生成した場合、このファイルをWebServicesAssemblerへの入力として使用し、これらの事前生成されたクラスのスキーマ定義の再生成を回避できます。

スキーマ・ドキュメントから生成されたクラスではなく、代替Javaクラスを使用してスキーマの複合型を表現する場合は、カスタム・タイプ・マッピング・ファイルの適切な<type-mapping>要素のコンテンツを編集する必要があります。また、要素を編集して、代替クラスのカスタム・シリアライザを含めることもできます。

例7-15のカスタム・タイプ・マッピング・ファイルのサンプルでは、genValueTypesコマンドにより、例7-8でJava値タイプの生成にスキーマが使用されたと仮定しています。

例7-15 事前生成された値タイプ・クラスを含むカスタム・タイプ・マッピング・ファイル

<?xml version="1.0" encoding="UTF-8"?>
    <oracle-webservices>
        <webservice-description name="unknown">
            <type-mappings
                xmlns:typens0="http://examples.webservices.oracle/customtypes"
                xmlns:typens2="http://www.w3.org/2001/XMLSchema"
                >
                <type-mapping
                    java-class="oracle.webservices.examples.customtypes.StringItem"
                    xml-type="typens0:StringItem">
                </type-mapping>
                <type-mapping
                    java-class="oracle.webservices.examples.customtypes.IntItem"
                    xml-type="typens0:IntItem">
                </type-mapping>
                <type-mapping
                    java-class="int"
                    xml-type="typens2:int">
                </type-mapping>
                <type-mapping
                    java-class="java.lang.String"
                    xml-type="typens2:string">
                </type-mapping>
            </type-mappings>
        </webservice-description>
    </oracle-webservices>

生成されたInitItemクラスではなく、oracle.webservices.examples.customtypes.MyInitItemおよびそのカスタム・シリアライザoracle.webservices.examples.customtypes.MyInitItemSerializerを使用し、java.lang.Stringにカスタム・シリアライザoracle.webservices.examples.customtypes.MyStringSerializerを使用するには、custom-type-mappings.xmlファイルを編集する必要があります。

  1. InitItemのインスタンスを置き換えます。

    1. InitItemのインスタンスを、適切な<type-mapping>要素のoracle.webservices.examples.customtypes.MyInitItemと置き換えます。

    2. <serializer>要素を<type-mapping>に追加して、MyInitItemのカスタム・シリアライザ・クラスoracle.webservices.examples.customtypes.MyInitItemSerializerを指定します。

      次に、custom-type-mappings.xmlの元の<type-mapping>要素の例を示します。

      <type-mapping
          java-class="oracle.webservices.examples.customtypes.IntItem"
          xml-type="typens0:IntItem">
      </type-mapping>
      

      次のようになります。

       <type-mapping
          java-class="oracle.webservices.examples.customtypes.MyIntItem"
          xml-type="typens0:IntItem">
          <serializer class="oracle.webservices.examples.customtypes.MyInitItemSerializer"/>
      </type-mapping>
      
  2. java.lang.Stringxsd:stringにマッピングするために<type-mapping>要素を編集します。エントリは次のようになります。

    <type-mapping>
       java-class="java.lang.String"
       xml-type="xsd:string">
       <serializer class="oracle.webservices.examples.customtypes.MyStringSerializer"/>
    </type-mapping>
    
  3. ファイルMyCustomTypeMappings.xmlの名前を変更し、プロジェクトのルート・ディレクトリにコピーします。

例7-16に、編集済のタイプ・マッピング・ファイルを示します。StringItemのタイプ・マッピング要素は、この事前生成済のクラスのスキーマ定義が再生成されないようにファイル内に残されています。

名前空間接頭辞の宣言(xmlns:xsd="http://www.w3.org/2001/XMLSchema")が追加されているため、タイプ・マッピング構成ファイルで使用できます。編集済のタイプ・マッピング構成ファイルでは、スキーマ名前空間(http://www.3.org/2001/XMLSchema)に定義されているstringスキーマ型を参照する必要があります。接頭辞xsdを定義すると、スキーマ型stringの修飾名としてxsd:stringを使用できます。

例7-16 編集済の値タイプ・クラスを含むカスタム・タイプ・マッピング・ファイル

<?xml version="1.0" encoding="UTF-8"?>
<oracle-webservices>
    <webservice-description name="unknown">
        <type-mappings
            xmlns:typens0="http://examples.webservices.oracle/customtypes"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <type-mapping
                java-class="java.lang.String"
                xml-type="xsd:string">
                <serializer class="oracle.webservices.examples.customtypes.MyStringSerializer"/>
            </type-mapping>
            <type-mapping
                java-class="oracle.webservices.examples.customtypes.MyIntItem"
                xml-type="typens0:IntItem">
                <serializer class="oracle.webservices.examples.customtypes.MyIntItemSerializer"/>
            </type-mapping>
            <type-mapping
                java-class="oracle.webservices.examples.customtypes.StringItem"
                xml-type="typens0:StringItem">
            </type-mapping>
        </type-mappings>
    </webservice-description>
</oracle-webservices>

カスタム・タイプ・マッピングおよびカスタム・シリアライザのクライアントのアセンブル方法

J2SEクライアント・サイド・プロキシ・ファイルを生成するには、WebServicesAssemblerのgenProxyコマンドを使用します。

java -jar wsa.jar -genProxy
     -wsdl http://localhost:8888/MyCustomTypes/MyCustomTypes?WSDL
     -output ./build/src/client

次に、このコマンドを説明します。


関連資料:

これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。


Webサービスのクライアント・サイド・プロキシを生成する際には、WebServicesAssemblerはカスタム・タイプを構成しないため、生成されたプロキシは、デフォルトでスキーマ型InitItemおよびStringItemを表す値タイプ(Bean)クラスの生成を試行します。その後、生成されたプロキシ・コードを使用してクライアント・プログラムを記述できます。

例7-17に、スキーマに存在するJava値タイプを使用するクライアント・プログラムを示します。

例7-17 生成されたデフォルトの値タイプを使用するクライアント・プログラム

package oracle.webservices.examples.customtypes;
    import javax.xml.rpc.ServiceFactory;
    import javax.xml.rpc.Stub;
    import examples.webservices.oracle.customtypes.*;
    public class MyCustomTypesClient {
        public static final String DEFAULT_URL
 ="http://localhost:8888/MyCustomTypes/MyCustomTypes";

        public static void main(String[] args) throws Exception {
            String address = DEFAULT_URL;
            ServiceFactory factory = ServiceFactory.newInstance();
            MyCustomTypes service = (MyCustomTypes) factory.loadService(MyCustomTypes.class);
            MyEndpointIntf proxy = (MyEndpointIntf)service.getPort(MyEndpointIntf.class);
            ((Stub) proxy)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, address);
            IntItem int1 = new IntItem();
            int1.setName("int1");
            int1.setValue(123);
            IntItem int2 = new IntItem();
            int2.setName("int2");
            int2.setValue(456);
            IntItem[] ints = { int1, int2 };
            StringItem str1 = new StringItem();
            str1.setName("string1");
            str1.setValue("foo");
            StringItem str2 = new StringItem();
            str2.setName("string2");
            str2.setValue("coo");
            StringItem[] strings = { str1, str2 };
            Items items = proxy.getItems(ints, strings);
            System.out.println("items.getMyIntItem : " + items.getMyIntItem().length);
            System.out.println("items.getStringItem: " + items.getStringItem().            length);
        }
}

前述したように、MyIntItemクラスは、Itemsクラスの開発に使用されています。Itemsタイプは、サービス・エンドポイント実装の戻り値として開発されています。MyIntItemSerializerおよびMyStringTypeSerializerは、OracleAS Web Servicesのランタイムで使用されます。WebServicesAssemblerによってデプロイ可能なEARファイルがアセンブルされる一方で、編集済のタイプ・マッピング構成のXMLファイルはEAR内のデプロイメント・ディスクリプタの作成に使用されるため、これらのカスタム・シリアライズはランタイムで適切に使用されます。

クライアント・コードにおけるカスタム・シリアライザの使用手順

Webサービスのクライアント・サイド・プロキシでカスタム・シリアライザを使用できます。これにより、クライアント・コードのサービスに定義されたカスタム・データ型を使用できるようになります。この項では、IntItemMyIntItemへのマッピングにMyIntItemSerializer例7-13参照)を使用し、string型のマッピングにMyStringSerializer例7-14参照)を使用する、Webサービスのクライアント・サイド・プロキシの作成方法を説明します。これを実行するには、クライアント・サイドのoracle-webservicesタイプ・マッピング構成ファイルMyCustomTypeMappings.xml例7-16参照)をgenProxyへの入力として使用する必要があります。

次に示す手順で、クライアント・プロキシにカスタム・シリアライザを追加するプロセスをまとめます。

  1. サーバー・サイドのカスタム・タイプ・マッピング・ファイルのクライアント・バージョンを指定します。

    この手順の詳細は、「クライアントのカスタム・タイプ・マッピング・ファイルの編集方法」で説明されています。

  2. WebServicesAssemblerのgenProxyコマンドを使用して、Webサービス・クライアント・プロキシを生成します。

    この手順の詳細は、「Webサービスのクライアント・サイド・プロキシのアセンブル方法」で説明されています。

  3. Webサービス・クライアントを記述します。

    この手順の詳細は、「カスタム・データ型を使用したWebサービス・クライアントの記述方法」で説明されています。

クライアントのカスタム・タイプ・マッピング・ファイルの編集方法

クライアント・サイドで使用されるカスタム・タイプ・マッピング・ファイルは、oracle-webservices-client-10_0.xsdスキーマに準拠している必要があります。クライアントのカスタム・タイプ・マッピング・ファイルの指定には、サービス側のカスタム・タイプ・マッピング・ファイルをテンプレートとして使用できます。ファイルを編集して、クライアント・サイドの適切なルート要素を指定します。

  • <oracle-webservices>要素を<oracle-webservices-clients>と置き換えます。

  • <webservice-description>要素および含まれる可能性のある任意の属性を<webservice-client>と置き換えます。

これらの編集を行うと、クライアント・サイドのカスタム・タイプ・マッピング・ファイル(この場合はMyCustomTypeMappings.xml)は、例7-18のコードのようになります。

例7-18 クライアント・サイドのカスタム・タイプ・マッピング・ファイル

<?xml version="1.0" encoding="UTF-8"?>
<oracle-webservice-clients>
   <webservice-client>
      <type-mappings xmlns:typens0="http://examples.webservices.oracle/customtypes"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <type-mapping
              java-class="java.lang.String"
              xml-type="xsd:string">
              <serializer class="oracle.webservices.examples.customtypes.MyStringSerializer"/>
          </type-mapping>
          <type-mapping
              java-class="oracle.webservices.examples.customtypes.MyIntItem"
              xml-type="typens0:IntItem">
             <serializer class="oracle.webservices.examples.customtypes.MyIntItemSerializer"/>
          </type-mapping>
          <type-mapping
              java-class="oracle.webservices.examples.customtypes.StringItem"
              xml-type="typens0:StringItem">
          </type-mapping>
       </type-mappings>
   </webservice-client>
</oracle-webservice-clients>

Webサービスのクライアント・サイド・プロキシのアセンブル方法

WebServicesAssemblerのgenProxyコマンドを使用して、Webサービスのクライアント・サイド・プロキシを生成します。ddFileName引数を使用して、クライアント・サイドのカスタム・タイプ・マッピング・ファイルを入力として指定します。genProxyコマンドにより、シリアライザを使用するクライアント・プロキシ・クラスが作成されます。

次に示すサンプルのgenProxyコマンドでは、クライアント・サイドのカスタム・タイプ・マッピング・ファイルMyCustomTypeMappings.xmlが入力として使用されています。

java -jar wsa.jar -genProxy
     -wsdl http://localhost:8888/MyCustomTypes/MyCustomTypes?WSDL
     -ddFileName ./MyCustomTypeMappings.xml
     -output ./build/src/client

次に、このコマンドを説明します。

  • genProxy: J2SE Webサービス・クライアントで使用できる静的プロキシ・スタブを作成します。

  • wsdl: WSDLドキュメントへの絶対ファイル・パス、相対ファイル・パスまたはURLを指定します。

  • ddFileName: Web Servicesに割り当てる設定を含むoracle-webservices.xmlデプロイメント・ディスクリプタを指定します。

  • output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。


関連資料:

これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。


カスタム・データ型を使用したWebサービス・クライアントの記述方法

生成されたプロキシ・コードを使用してクライアント・プログラムを記述すると、デフォルトのJavaデータ型ではなく、カスタム・データ型をコールできます。例7-19に、デフォルトのIntItemデータ型ではなくMyIntItemカスタム・データ型を使用するクライアント・コードを示します。

例7-19 カスタム・タイプ・マッピングおよびカスタム・シリアライザを含むクライアント・コード

ServiceFactory factory = ServiceFactory.newInstance();
MyCustomTypes service = (MyCustomTypes) factory.loadService(MyCustomTypes.class);
MyEndpointIntf proxy = (MyEndpointIntf)service.getPort(MyEndpointIntf.class);
((Stub) proxy)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, address);

    MyIntItem int1 = new MyIntItem("int1", 123);
    MyIntItem int2 = new MyIntItem("int2", 456);
    MyIntItem [] ints = { int1, int2 };

    StringItem str1 = new StringItem();
    str1.setName("string1");
    str1.setValue("foo");
    StringItem str2 = new StringItem();
    str2.setName("string2");
    str2.setValue("coo");
    StringItem[] strings = { str1, str2 };

    Items items = proxy.getItems(ints, strings);

制限事項

「Java値タイプのカスタム・シリアライズ」を参照してください。

追加情報

詳細は、次を参照してください。