この章では、カスタム・シリアライズ・フレームワーク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値タイプのカスタム・マッピングを作成する必要はありません。
関連資料:
|
この章の内容は、次のとおりです。
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オブジェクトにデシリアライズされます。
このインタフェースには次のメソッドがあります。
public SOAPElement serialize(QName tagName, Object object)
JavaオブジェクトをSAAJ SOAPElement
インスタンスのXMLフラグメントにマーシャリングするために、serialize
メソッドを実装します。このシリアライザ実装を再利用可能にするためには、serialize
の実装でtagName
パラメータの値を、戻されるSOAPElement
インスタンスの最上位レベルの要素のタグ名として使用する必要があります。これは、XMLスキーマcomplexType
が異なる要素定義に使用される可能性があるためです。
public Object deserialize(SOAPElement element)
SAAJ SOAPElement
インスタンスのXMLフラグメントをJavaオブジェクトにアンマーシャリングするために、deserialize
メソッドを実装します。
public void init(Map prop)
OracleAS Web Servicesのランタイムによってコールされ、SOAPElementSerializer
実装のインスタンスがサービスに配置されることを伝達します。init
メソッドは、カスタム・タイプ・マッピング・ファイルで対応するシリアライザ要素の下に指定されている、init-param
要素から作成されたMap
のインスタンスを使用してコールされます。Map
インスタンスのkey
タイプおよびvalue
タイプのどちらもjava.lang.String
です。
key
およびvalue
値は、ユーザーにより定義され、oracle-webservices.xml
にある<serializer>
セクションの<init-param>
要素のname
およびvalue
属性から取得されます。たとえば、次のoracle-webservices.xml
フラグメントでは、myParam
がkey
タイプで、myValue
がvalue
です。
...
<serializer java-class="mySerializer">
<init-param name="myParam" value="myValue">
</serializer>
...
インタフェースの実装には、デフォルトの引数を使用しないコンストラクタが必要です。SOAPElementSerializer
の詳細は、『Oracle Application Server Web Services Java API Reference』で説明されています。
Webサービスでカスタム・シリアライズを使用するには、カスタムJava値タイプ・クラスのSOAPElementSerializer
の実装を指定します。また、カスタムJava値タイプ・クラス、およびJava値タイプ・クラスと表現するXMLスキーマ型の間のマッピングを定義するXML構成ファイルも指定する必要があります。これは次の項で説明します。
関連資料: XML型のマッピング構成ファイルの詳細は、次の項を参照してください。 |
この項では、Java値タイプ・クラスのカスタム・シリアライザの実装手順を説明します。
XMLスキーマ型として表現するカスタムJava値タイプ・クラスを定義します。
クラスのカスタム・シリアライザ実装を定義します。
サービス・エンドポイント・インタフェースとその実装を定義します。
トップダウン方式でWeb Servicesをアセンブルする場合、WebServicesAssemblerによりサービス・エンドポイント・インタフェースがWSDLから生成されます。ボトムアップ方式でWeb Servicesをアセンブルする場合、Javaサービス・エンドポイント・インタフェースを指定する必要があります。
カスタムJava値タイプ・クラスを表現する際に使用されるスキーマ型を示すoracle-webservicesタイプ・マッピング構成のXMLファイルを作成します。
カスタム・タイプをクライアント・コードに含めます。
この手順は、次の項で詳しく説明します。
この項では、XMLスキーマ型へのマッピングに使用可能なカスタムJava値タイプ・クラスを説明します。
注意:
|
例7-1に、カスタムJava値タイプ・クラスの定義を示します。JAX-RPCでは、xsd:dateTime
はjava.util.Calendar
またはjava.util.Date
によって表現されます。ただし、これらのクラスのいずれかを使用せずに、独自のデータ・クラスを実装するとします。例7-1では、単一のユーザー定義のJava値タイプ・クラスoracle.demo.custom_type.MyDate
を示します。このクラスはSerializable
を実装し、String
値を取得および設定するメソッドを含みます。
Webサービス実装でJava値タイプ・クラスを使用し、XMLスキーマ型でWSDLのクラスを表現するには、SOAPElementSerializer
の実装を指定する必要があります。実装により、Java値クラス・タイプとXMLスキーマ型の間のシリアライズとデシリアライズが処理されます。
例7-2にMyDateSerializer
を示します。これは、例7-1に示すMyDate
値タイプ・クラスのSOAPElementSerializer
実装です。この実装により、Webサービス・エンドポイント・インタフェースでMyDate
を使用し、MyDate
とxsd: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; } }
この項では、ユーザー定義のBeanをWeb Servicesとして使用するJavaサービス・エンドポイント・インタフェースの公開方法を説明します。例7-3および例7-4に、Javaサービス・エンドポイント・インタフェースと、oracle.demo.custom_type.MyDate
クラスを使用する実装を示します。例7-5に、インタフェースで使用されるユーザー定義のBeanタイプであるMyDateBean
の定義を示します。
JAX-RPCの要件を満たすために、例7-3のMyDateServiceEndpoint
インタフェースで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タイプ・マッピング構成のXMLファイルは、カスタムJava値タイプ・クラスを表現するXMLスキーマ型を指定します。ファイルには、シリアライズするXMLスキーマ型、カスタムJava値タイプ・クラスおよびカスタム・シリアライズを実行するクラスを指定する<type-mapping>
が用意されています。表7-1に、<type-mapping>
要素のコンテンツを説明します。
表7-1 <type-mapping>要素のコンテンツ
属性または要素名 | 説明 |
---|---|
java-class |
|
serializer-class |
|
xml-type |
|
スキーマ・ファイル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:dateTime
にMyDate
インスタンスを使用できるようになります。
例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); ...
カスタム・シリアライザを使用して、サービス・エンドポイント・インタフェースのカスタムJava値タイプの、Java値タイプからXMLスキーマ型への特別なマッピングを指定できます。これにより、カスタムJava値タイプを、定義済のタイプであるWSDLのデフォルトのJAX-RPCマッピングに置き換えられます。WebServicesAssemblerにより、カスタムJava値タイプが処理され、インタフェースの適切なコードが生成されます。
たとえば、java.util.Calendar
からスキーマ定義のXML型xsd:dateTime
へのデフォルト・マッピングを、カスタムJava値タイプ・クラスMyDate
に変更できます。カスタム・シリアライザにより、サービス・エンドポイント・インタフェースに適切なコードを生成できるようになります。
カスタムJava値タイプ・クラス、SOAPElementSerializer
実装およびタイプ・マッピング構成ファイルを指定する他に、この点も一般的なトップダウン方式のWebサービスの開発に非常に似ています。
次に示す一般的な手順に従って、カスタム・シリアライザを使用するWebサービスを開発します。
WebServicesAssemblerのgenInterface
コマンドおよびカスタム・シリアライザを実行して、カスタム・タイプ・マッピングを持つサービス・エンドポイント・インタフェースを生成します。
サービス・エンドポイント・インタフェースを実装します。
WebServicesAssemblerのtopdownAssemble
コマンドを再度実行し、WebサービスをアセンブルしてEARにパッケージ化します。
次の項では、これらの手順をさらに詳細に説明します。
開始する前に、次のファイルと情報を用意してください。
カスタムJava値タイプ・クラス。
カスタムJava値タイプ・クラスの詳細は、「カスタムJava値タイプ・クラスの定義方法」を参照してください。
カスタムJava値タイプ・クラスのSOAPElementSerializer
インタフェースの実装。
SOAPElementSerializer
インタフェースの実装の詳細は、「Java値タイプ・クラスのカスタム・シリアライザ実装の定義方法」を参照してください。
カスタムJava値タイプ・クラスを使用するWSDL。
oracle-webservicesタイプ・マッピング構成のXMLファイル。
oracle-webservicesタイプ・マッピング構成の作成の詳細は、「oracle-webservicesタイプ・マッピング構成の作成方法」を参照してください。
次の手順では、トップダウン方式でのWebサービス開発にカスタム・シリアライズを使用する方法を説明します。
前提条件のセクションで説明されているファイルを、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
に格納されます。
生成されたインタフェースおよびタイプ・クラスをコンパイルします。
次に例を示します。
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ビルド・スクリプトを適切に設定してください。
サービス・エンドポイント・インタフェースを実装します。
実装には、生成されたJavaインタフェース内のすべてのメソッドと一致するメソッド・シグネチャが必要です。
サービス実装をコンパイルします。
たとえば、Impl
クラスが保存されているディレクトリと同じディレクトリでインタフェースのソースが生成された場合は、手順2と同じコマンドを使用できます。そうでない場合は、path
引数の値を変更する必要があります。
サービス・エンドポイント実装、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の使用方法」を参照してください。 |
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で上書きしたくない場合に、この引数を指定します。
関連資料:
|
カスタム・シリアライザを使用して、サービス・エンドポイント・インタフェースで使用される特定のJava値タイプの、Java値タイプからXMLスキーマ型への特別なマッピングを指定できます。これは、Java値タイプからXMLスキーマ型への特別なマッピングを説明する独自のカスタム・スキーマ・ドキュメントを使用できることを意味します。Java値タイプからXMLスキーマ型への特別なマッピングを指定した場合は、WebServicesAssemblerでこれらのタイプのスキーマ定義を生成する必要はありません。
ボトムアップ方式でのWebサービスの開発であるため、WebServicesAssemblerによりWSDLが生成されます。WSDLでは、値のタイプにスキーマを生成するかわりに、WebServicesAssemblerにより指定する1つ以上のスキーマ・ドキュメントがインポートされます。
開始する前に、次のファイルと情報を用意してください。
カスタムJava値タイプ・クラス。これらのクラスがクラスパスに存在する必要があります。
カスタムJava値タイプ・クラスの詳細は、「カスタムJava値タイプ・クラスの定義方法」を参照してください。
カスタムJava値タイプを説明するスキーマ・ドキュメント。
カスタムJava値タイプ・クラスのSOAPElementSerializer
インタフェースの実装。
SOAPElementSerializer
インタフェースの実装の詳細は、「Java値タイプ・クラスのカスタム・シリアライザ実装の定義方法」を参照してください。
特別なカスタムJava値タイプ・クラスを使用するJavaサービス・エンドポイント・インタフェース。
サービス実装エンドポイントの詳細は、「Java値タイプ・クラスを使用するサービス・エンドポイント・インタフェースの定義方法」を参照してください。
oracle-webservicesタイプ・マッピング構成のXMLファイル。
oracle-webservicesタイプ・マッピング構成ファイルの作成の詳細は、「oracle-webservicesタイプ・マッピング構成の作成方法」を参照してください。
次の説明では、カスタム・タイプ・マッピングを必要とする、ボトムアップ方式でのWebサービスをアセンブルします。
前提条件のセクションで説明されているファイルを、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の使用方法」を参照してください。 |
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サービス開発では、スキーマ・ドキュメントを使用してWebServicesAssemblerを起動し、Webサービスをアセンブルする前にJava値タイプ・クラス(Bean)を生成します。
スキーマの複合型から生成されたJava値クラスは、JAX-RPC値タイプ(Bean)パターンの要件に準拠しているため、カスタム・シリアライザは不要です。JAX-RPCにより提供されているデフォルト・マッピングで問題ない場合は、カスタム・シリアライザを実装する必要はありません。
ただし、XMLとJava間のデフォルトのマーシャリングを変更する必要がある場合は、生成されるJava値タイプ・クラス用にカスタム・シリアライザを実装する必要があります。
次に示す一般的な手順に従って、スキーマからWebサービスをアセンブルします。
スキーマ・ドキュメントを使用してWebServicesAssemblerを実行し、Java値タイプ・クラス、標準のJAX-RPCマッピング・ファイル、およびoracle-webservicesタイプ・マッピング構成のXMLファイル(custom-type-mappings.xml
)を生成します。
独自のサービス・エンドポイント・インタフェースとその実装を開発します。ここでは、インタフェースおよび実装が、手順1のスキーマ・ドキュメントで使用されていないカスタムJavaデータ型を1つ以上使用すると仮定しています。
デフォルトのマーシャリングが1つ以上のクラスで不十分な場合は、カスタム・シリアライザを作成して独自のマーシャリング・ロジックを実装します。
oracle-webservicesタイプ・マッピング構成のXMLファイルを編集し、カスタム・シリアライザを含めます。また、代替のJavaクラスを生成された任意のJava値タイプ・クラスに置き換えることも可能です。
WebServicesAssemblerを再度実行し、今度はWSDLドキュメントを生成します。JAX-RPCマッピング・ファイル、編集されたoracle-webservicesタイプ・マッピング構成のXMLファイル、スキーマ・ドキュメント、生成されたJava値タイプ、およびサービス・エンドポイント・インタフェースとその実装を入力します。また、作成した場合は、カスタム・シリアライザも含めます。
Java値タイプから生成するのではなく、生成されたWSDLにより、指定したスキーマがインポートされます。
WebServicesAssemblerにより、生成されたWSDL、およびすべての実装ファイルとデプロイメント・ディスクリプタがデプロイ可能なEARとアセンブルされ、Webサービスが有効化されます。
開始する前に、次のファイルと情報を用意してください。
スキーマ・ドキュメント。
Java値タイプ・クラスを生成するスキーマ・ドキュメントの例は、「スキーマ・ドキュメントのサンプル」を参照してください。
サービス・エンドポイント・インタフェースとその実装。
ここでは、インタフェースおよび実装が、スキーマ・ドキュメントで使用されていないカスタムJavaデータ型を1つ以上使用すると仮定しています。サービス・エンドポイント・インタフェースのサンプルおよび手順1で説明したスキーマ・ドキュメントに表示されないカスタムJavaデータ型を使用する実装は、「サービス・エンドポイント・インタフェースおよび実装のサンプル」を参照してください。
スキーマの複合型を表すJavaカスタム型の定義。
サンプル・インタフェースおよび実装で使用したJavaカスタム・データ型の実装は、「Javaカスタム型の実装」を参照してください。
カスタムのデフォルト・マーシャリング・ロジックを指定している場合には、カスタム・シリアライザも作成して独自のマーシャリング・ロジックを実装する必要があります。
シリアライザおよびマーシャリング・ロジックの実装方法は、「カスタム・マーシャリング・ロジックを使用したシリアライザの実装方法」で説明されています。
この章では、複合型を含む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サービスを開発する方法を説明します。
スキーマ・ドキュメントを使用して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ファイル用に生成されたサーバー・サイド・インスタンスです。
生成された値タイプを/build/classes/service
ディレクトリにコンパイルします。
genValueTypes
コマンドはクラスをコンパイルしません。この手順は手動で実行する必要があります。IntItem
クラスを削除することも、コンパイルから除外することもできます。これは、このクラスにカスタム・シリアライザを指定するためです。
カスタム・シリアライザを実装します。この例では、oracle.webservices.examples.customtypes.MyIntItem
とInitItem
をマッピングするシリアライザ、およびjava.lang.String
とxsd:string
をマッピングするシリアライザの2つのカスタム・シリアライザが必要です。
これらのシリアライザの実装のサンプルは、「マーシャリング・ロジックを使用したシリアライザ実装の定義」で説明されています。
サービス・エンドポイント・インタフェースとその実装を開発します。
oracle.webservices.examples.customtypes.MyInitItem
および生成されたJava値タイプ・クラスを使用する、サービス・エンドポイント・インタフェースの実装のサンプルは、「サービス・エンドポイント・インタフェースおよび実装のサンプル」で説明されています。
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ファイルの編集方法」で説明されています。
今度は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の使用方法」を参照してください。 |
サービスをデプロイし、アプリケーションをバインドします。
通常の方法で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デプロイメント・ガイド』で説明されています。
次のいずれかの方法でクライアントを開発します。
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-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
のカスタム・シリアライザ実装のサンプルを示します。シリアライズ機能を指定するために、カスタム・シリアライザMyInitItemSerializer
でSOAPElementSerializer
クラス、およびそのserialize
とdeserialize
メソッドを実装しています。
例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.String
をxsd:string
にマッピングするためのカスタム・シリアライズ実装のサンプルを示します。シリアライズ機能を指定するために、カスタム・シリアライザMyStringSerializer
でSOAPElementSerializer
クラス、およびそのserialize
とdeserialize
メソッドを実装しています。また、独自の文字列書式や検証コードを入力できるプレースホルダも指定しています。
例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(); } }
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
ファイルを編集する必要があります。
InitItem
のインスタンスを置き換えます。
InitItem
のインスタンスを、適切な<type-mapping>
要素のoracle.webservices.examples.customtypes.MyInitItem
と置き換えます。
<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>
java.lang.String
をxsd:string
にマッピングするために<type-mapping>
要素を編集します。エントリは次のようになります。
<type-mapping> java-class="java.lang.String" xml-type="xsd:string"> <serializer class="oracle.webservices.examples.customtypes.MyStringSerializer"/> </type-mapping>
ファイル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
次に、このコマンドを説明します。
genProxy
: J2SE Webサービス・クライアントで使用できる静的プロキシ・スタブを作成します。
wsdl
: WSDLドキュメントへの絶対ファイル・パス、相対ファイル・パスまたはURLを指定します。
output
: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。
関連資料: これらの引数の詳細は、『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サービスのクライアント・サイド・プロキシでカスタム・シリアライザを使用できます。これにより、クライアント・コードのサービスに定義されたカスタム・データ型を使用できるようになります。この項では、IntItem
のMyIntItem
へのマッピングにMyIntItemSerializer
(例7-13参照)を使用し、string
型のマッピングにMyStringSerializer
(例7-14参照)を使用する、Webサービスのクライアント・サイド・プロキシの作成方法を説明します。これを実行するには、クライアント・サイドのoracle-webservicesタイプ・マッピング構成ファイルMyCustomTypeMappings.xml
(例7-16参照)をgenProxy
への入力として使用する必要があります。
次に示す手順で、クライアント・プロキシにカスタム・シリアライザを追加するプロセスをまとめます。
サーバー・サイドのカスタム・タイプ・マッピング・ファイルのクライアント・バージョンを指定します。
この手順の詳細は、「クライアントのカスタム・タイプ・マッピング・ファイルの編集方法」で説明されています。
WebServicesAssemblerのgenProxy
コマンドを使用して、Webサービス・クライアント・プロキシを生成します。
この手順の詳細は、「Webサービスのクライアント・サイド・プロキシのアセンブル方法」で説明されています。
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>
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の使用方法」を参照してください。 |
生成されたプロキシ・コードを使用してクライアント・プログラムを記述すると、デフォルトの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);
詳細は、次を参照してください。
Webサービスをトップダウン方式でアセンブルする場合は、『Oracle Application Server Web Services開発者ガイド』の「WSDLからのWebサービスのアセンブル」を参照してください。
Javaクラスを使用してWebサービスをアセンブルする場合は、『Oracle Application Server Web Services開発者ガイド』の「Javaクラスを使用したWebサービスのアセンブル」を参照してください。
EJBを使用してWebサービスをアセンブルする場合は、『Oracle Application Server Web Services開発者ガイド』の「EJBを使用したWebサービスのアセンブル」を参照してください。
JMSトピックおよび宛先を使用してWebサービスをアセンブルする場合は、『Oracle Application Server Web Services開発者ガイド』の「JMS宛先を使用したWebサービスのアセンブル」を参照してください。
PL/SQLパッケージ、SQL問合せ、DML文、Oracle Streams AQまたはサーバー・サイドJavaクラスなどのデータベース・リソースを使用してWebサービスをアセンブルする場合は、『Oracle Application Server Web Services開発者ガイド』の「データベースWebサービスのアセンブル」を参照してください。
J2EE Webサービス・クライアントをアセンブルする場合は、『Oracle Application Server Web Services開発者ガイド』の「J2EE Webサービス・クライアントのアセンブル」を参照してください。
J2SE Webサービス・クライアントをアセンブルする場合は、『Oracle Application Server Web Services開発者ガイド』の「J2SE Webサービス・クライアントのアセンブル」を参照してください。
WebServicesAssemblerコマンドを使用してWebサービス・アーティファクトをアセンブルする場合は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。
クライアント・コードのコンパイルに必要なJARについては、『Oracle Application Server Web Services開発者ガイド』の「Webサービス・クライアントのAPIおよびJAR」を参照してください。
Webサービス管理構成を含むoracle-webservices.xml
デプロイメント・ディスクリプタの内容については、『Oracle Application Server Web Services開発者ガイド』の「Webサービスのパッケージ化およびデプロイ」を参照してください。