この章では、Oracle Application Server Web ServicesによるWebサービス起動フレームワーク(WSIF)のサポートについて説明します。
この章の内容は、次のとおりです。
WSIFには、JAX-RPC SOAPクライアントAPIを直接使用するかわりとして、Webサービスの異なるメッセージ・プロトコルの表現を処理するための標準のAPIが用意されています。WSIF APIを使用すると、クライアントはネイティブのプロトコルを使用してサービスと通信できます。
WSIF APIにより、Webサービスは、Javaクラス、EJBまたはデータベース・リソースなどのWebサービス・コンポーネントと単一のインタフェースを使用して通信できます。SOAPのみを解釈するJAX-RPCに加え、WSIFクライアントはRMI、IIOPまたはJDBCなど、その他のプロトコルを直接使用できます。
様々なメッセージ・プロトコルをサポートするために、WSDLに異なるWSIFバインディングを追加できます。SOAPバインディングを追加するSOAPプロトコルとは大きく異なります。WSIFおよびSOAPバインディングは、同じWSDL内に共存できます。これにより、特定のサービスにネイティブおよびSOAPバインディングの両方を定義できます。たとえば、WSIFポートおよびSOAPポートを使用してEJBを公開できます。異なるプロトコルを使用しているクライアントでも、同じWebサービスにアクセスできます。サービスとの通信に使用するプロトコルは、クライアントで、SOAPまたはWSIFバインディングのいずれかのバインディングを選択することで決定できます。
|
注意: WSIF起動により、プリミティブおよびNULL値が許可されているXMLスキーマ型が、プリミティブJava型にマッピングされます。これにより、XML nil値の表現は許可されません。これを回避するには、WSDLでSOAP-encoded XML型を使用します。 |
WSIFには、Apache Software Foundationが出資しています。WSIFの詳細は、次のWebサイトを参照してください。
WSIFアーキテクチャでは、クライアントとWebサービス間の通信はWSDLを使用することで可能になります。WSDLは、ソフトウェア・インタフェースの正規化された説明です。
図9-1に、OracleAS Web ServicesのWSIFアーキテクチャを示します。次の手順で、アーキテクチャ内のデータ・フローを説明します。
WSDLのサービスの要約説明部分の内容に従ってWSIFクライアントをプログラムします。WSDLのこの部分には、ポート・タイプ、操作およびメッセージ交換が含まれています。
実行時に、WSIFクライアントにより、WSIFのランタイムがどのプロバイダを使用するかを決定する、WSDL内の具体的なバインディングが選択されます。プロバイダはプロトコル固有のコードの一部で、異なるWSIFバインディングの実装をWSDLに作成します。
WSIFクライアントは、WSIF APIにコールを作成してWebサービスを起動します。このAPIは、WSDLのサービスの要約説明部分に基づいています。要約説明に基づいてサービスを起動することにより、実装方法、プロトコルまたは配置場所にかかわらずサービスを使用できます。
手順2で選択したバインディングに基づいて、カーネルのWSIFのランタイムが使用するプロバイダを決定します。
プロバイダがWebサービスと通信します。
サービスは、スタブを生成する必要なく、動的に起動されます。
WSIFは、JAX-RPC(SOAP)、Javaクラス、EJBおよびデータベース・リソースを公開するWebサービス・クライアントのプロバイダをサポートしています。独自のプロバイダを定義することもできます。独自のプロバイダの定義については、このマニュアルでは説明しません。このトピックの詳細は、Apache Software FoundationのWSIFのWebページを参照してください。
次の項では、WSDLにWSIF情報を挿入するWebServicesAssemblerコマンドおよびAntタスクを説明します。
この項の内容は、次のとおりです。
WSDLにWSIF Java拡張を挿入するために、OracleAS Web Servicesには、WebServicesAssemblerのassembleまたはgenWsdlコマンドとともに使用できる2つの引数が用意されています。
wsifJavaBinding
wsifJavaPort
assembleまたはgenWsdlコマンドを使用してJavaクラスに基づいてWebサービスをアセンブルする場合、wsifJavaBindingおよびwsifJavaPort引数を使用してWSIFバインディングをリクエストできます。これらの引数により、適切なWSDL拡張がWSIFバインディングという形で追加されます。これにより、WSIFクライアントはWebサービスとして公開されているJavaクラスにアクセスできます。
単一のポートにWSIF Javaバインディングを構成する際には、wsifJavaBindingまたはwsifJavaPort引数を使用できます。wsifJavaBinding引数を使用すると、使用するWSDLにWSIFポートを持てますが、追加のSOAPポートは持てません。wsifJavaPort引数を使用すると、Antタスク内にタイプの異なる複数のポートを指定できます。
wsifJavaBinding引数はコマンドラインまたはAntタスクで使用できますが、wsifJavaPortはAntタスクでのみ使用できます。
|
関連資料:
|
Javaポートに対するWSIFエンドポイントは、wsifJavaBindingまたはwsifJavaPortを使用して構成できます。
wsifJavaBinding引数は、assembleまたはgenWsdlコマンドで使用して、単一のポートに対するWSIF Javaバインディングを指定できるフラグです。
wsifJavaBinding引数を使用した場合、classNameにも値を指定する必要があります。className引数により、WSDLの<port>要素のjava:address要素の値が指定されます。
例9-1に、wsifJavaBindingをコールするgenWsdlのWebServicesAssemblerコマンドラインを示します。例9-2に、対応するAntタスクを示します。引数により、WSDLの<port>要素のjava:address要素に、classname="oracle.demo.hello.HelloImpl"が移入されます。変数${wsdemo.common.class.path}はクラスパスを表します。
例9-1 wsifJavaBindingを使用して単一のJavaポートを構成するコマンドライン
java -jar wsa.jar -genWsdl
-output wsdl
-style rpc
-use literal
-wsifJavaBinding true
-interfaceName oracle.demo.hello.HelloInterface
-className oracle.demo.hello.HelloImpl
-classpath ${wsdemo.common.class.path}:build/classes
例9-2 wsifJavaBindingを使用して単一のJavaポートを構成するAntタスク
<oracle:genWsdl
output="wsdl"
style="rpc"
use="literal"
wsifJavaBinding="true"
>
<oracle:porttype
interfaceName="oracle.demo.hello.HelloInterface"
className="oracle.demo.hello.HelloImpl"
</oracle:porttype>
<oracle:classpath>
<oracle:pathelement path="${wsdemo.common.class.path}"/>
<oracle:pathelement location="build/classes"/>
</oracle:classpath>
</oracle:genWsdl>
次に、このコマンドラインおよびAntタスクの例の説明をします。
genWsdl: Javaインタフェースを使用してボトムアップ方式でWebサービスをアセンブルするWSDLおよびJAX-RPCマッピング・ファイルを生成します。
output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。
style: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のstyle属性を指定します。
use: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のuse属性を指定します。
wsifJavaBinding: ボトムアップ方式でのWebサービス・アセンブリで使用し、WSIF JavaバインディングをWSDLに追加します。trueの場合、Java実装クラスのclassNameも指定する必要があります。WebServicesAssemblerにより、WSDLに、SOAPバインディングに加え、ネイティブWSIF Javaバインディングが生成されます。
interfaceName: サービス・エンドポイント・インタフェース(SEI)を含むJavaクラス名(パッケージ名を含みます)を指定します。
className: Webサービスの実装クラスであるクラス名(パッケージ名を含みます)を指定します。
classpath: WebServicesAssemblerに指定されるすべてのユーザー作成クラスを含むクラスパスを指定します。作成済の値タイプ・クラスまたは例外があり、WebServicesAssemblerで上書きしたくない場合に、この引数を指定します。
|
関連資料: これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。 |
wsifJavaPort引数はAntタスクでのみ使用できます。通常wsifJavaPortは、複数のポートにWSIF Javaバインディングを指定する際に使用しますが、単一のポートの指定に使用することもできます。引数には、WSIFポート名、各ポートのJavaクラス名、カスタム・クラス・ローダーおよびそのクラスパスの指定を可能にする属性もあります。これらの属性は、WSDLの<port>要素のjava:address要素に渡されます。
表9-1に、wsifJavaPort引数で使用される属性を説明します。属性は、すべてオプションです。
表9-1 wsifJavaPort引数の属性
| 属性 | 説明 |
|---|---|
|
Javaクラス・ローダーの名前を指定します。この属性に値を指定しない場合は、システムのクラス・ローダーの値が使用されます。 |
|
|
実装クラスの名前を指定します。この属性に値を指定しない場合、WebServicesAssemblerは親Antタスクのクラス名を使用します(親Antタスクが指定されている場合)。 |
|
|
Javaクラス・ローダーのクラスパスを指定します。この属性に値を指定しない場合は、システムのクラスパスが使用されます。 |
|
|
WebサービスのWSIFポートの名前を指定します。この名前は、WSDLの |
例9-3のgenWsdlのAntタスクにより、WSDLのバインディング、バインディング操作およびポート句にWSIF Javaバインディング・コードが挿入されます。wsifJavaPort引数のclassName属性として使用されるHelloImplクラスには、String型のgreetingパラメータを使用するsayHelloメソッドが含まれます。変数${additional.class.path}はクラスパスを表します。
例9-3 wsifJavaPortを使用した単一のJavaポートの構成
<oracle:genWsdl
output="wsdl"
style="rpc"
use="literal"
>
<oracle:porttype
interfaceName="oracle.demo.hello.HelloInterface">
<oracle:wsifJavaPort name="HelloServiceJavaPort"
className="oracle.demo.hello.HelloImpl" />
</oracle:porttype>
<oracle:classpath>
<oracle:pathelement path="${additional.class.path}" />
<oracle:pathelement location="build/classes" />
</oracle:classpath>
</oracle:genWsdl>
次に、このAntタスクを説明します。
genWsdl: Javaインタフェースを使用してボトムアップ方式でWebサービスをアセンブルするWSDLおよびJAX-RPCマッピング・ファイルを生成します。
output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。
style: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のstyle属性を指定します。
use: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のuse属性を指定します。
porttype: このタグにより、異なるインタフェースをWebサービスに構成できます。
interfaceName: サービス・エンドポイント・インタフェース(SEI)を含むJavaクラス名(パッケージ名を含みます)を指定します。
wsifJavaPort: WSIF Javaバインディングを複数のポートに指定できます。
className: Webサービスの実装クラスであるクラス名(パッケージ名を含みます)を指定します。
classpath: WebServicesAssemblerに指定されるすべてのユーザー作成クラスを含むクラスパスを指定します。作成済の値タイプ・クラスまたは例外があり、WebServicesAssemblerで上書きしたくない場合に、この引数を指定します。
|
関連資料: これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。 |
例9-4に、前述の例でAntタスクによりWSDLのバインディング、バインディング操作およびポート句に挿入された、WSIF Javaバインディング・コードを示します。
例9-4 WSIF JavaバインディングのWSDL拡張
...
<java:binding/>
<format:typeMapping encoding="Java" style="Java">
<format:typeMap typeName="xsd:string" formatType="java.lang.String"/>
</format:typeMapping>
...
<java:operation
methodName="sayHello"
parameterOrder="greeting"
methodType="instance"
returnType="result" />
...
<port name="HelloServiceJavaPort" binding="tns:JavaBinding">
<java:address className="oracle.demo.hello.HelloImpl" />
</port>
...
assembleおよびgenWsdlコマンドとともにwsifJavaPort引数を使用して、複数のJavaポートに対するWSIFバインディングを定義できます。例9-5に、HelloServiceJavaPortという名前のWSIFポート、およびHelloServiceSoapPortという名前のSOAPポートを作成するAntタスクを示します。SOAPポートは、<oracle:port name="... "/>サブタスクを追加することで作成されます。classNameが親Antタスクで宣言されていることに注意してください。変数${additional.class.path}はクラスパスを表します。表9-1に、wsifJavaPortで使用される属性を説明します。
例9-5 wsifJavaPortを使用したWSIF JavaポートおよびSOAP Javaポートの構成
<oracle:genWsdl
output="wsdl"
style="rpc"
use="literal"
>
<oracle:porttype
interfaceName="oracle.demo.hello.HelloInterface"
className="oracle.demo.hello.HelloImpl">
<oracle:wsifJavaPort name="HelloServiceJavaPort" />
<oracle:port name="HelloServiceSoapPort" />
</oracle:porttype>
<oracle:classpath>
<oracle:pathelement path="${additional.class.path}" />
<oracle:pathelement location="build/classes" />
</oracle:classpath>
</oracle:genWsdl>
WSIFフレームワーク定義に準拠するために、OracleAS Web ServicesはJavaクラスをWebサービスとして表現できるバインディング情報をWSDLに挿入します。例9-6には、それらの拡張のXMLスキーマ定義を示します。
例9-4に、その他のバインディング、バインディング操作およびポート句をWSDLに追加してWSIFサービスを記述する方法を示します。
例9-6 WSIF Javaバインディングをサポートするためのスキーマ定義
... <!-- Java binding --> <binding ... > <java:binding/> <format:typeMapping style="uri" encoding="..."/>? <format:typeMap typeName="qname"|elementName="qname" formatType="nmtoken"/>* </format:typeMapping> ... <operation>* <java:operation methodName="nmtoken" parameterOrder="nmtoken"? returnPart="nmtoken"? methodType="instance|static|constructor"? />? <input name="nmtoken"? />? <output name="nmtoken"? />? <fault name="nmtoken"? />? </operation> </binding> .... <service ... > <port name="nmtoken" >* <java:address className="nmtoken" classPath="nmtoken"? classLoader="nmtoken"? /> </port> </service> ...
この項の内容は、次のとおりです。
WSDLにWSIF EJB拡張を挿入するために、WebServicesAssemblerツールにはejbAssembleまたはgenWsdlコマンドとともに使用できる2つの引数が用意されています。
wsifEjbBinding
wsifEjbPort
ejbAssembleコマンドを使用してEJBに基づいてWebサービスをアセンブル際には、wsifEjbBindingまたはwsifEjbPort引数を使用してWSIFバインディングをリクエストできます。
これらの引数により、Webサービスとして公開されているEJBへのWSIFクライアントによるアクセスを可能にする適切なWSDL拡張が追加されます。
単一のポートにWSIF EJBバインディングを構成する際には、wsifEjbBindingまたはwsifEjbPort引数を使用できます。複数のポートに対してWSIF EJBバインディングを構成するには、wsifEjbPort引数を使用する必要があります。
wsifEjbBinding引数はコマンドラインまたはAntタスクで使用できますが、wsifEjbPortはAntタスクでのみ使用できます。
|
関連資料:
|
OracleAS Web Servicesにより、Oracle独自の使用方法でJ2SE 5.0 Webサービス注釈およびバージョン3.0 EJBのWSIFバインディングをアセンブルできます。OracleAS Web Servicesでは、@WSIFEJBBinding注釈(oracle.webservices.annotations.@WSIFEJBBinding)を定義して、EJBのインタフェース・ファイルに追加できます。ファイルをコンパイルすると、WSDLのEJB WSIFバインディングおよびEJBポートが生成されます。
@WSIFEJBBinding注釈の詳細およびその使用方法は、『Oracle Application Server Web Services開発者ガイド』の「OracleによるJ2SE 5.0 JDK注釈への追加」を参照してください。
EJBポートに対するWSIFエンドポイントは、wsifEjbBindingまたはwsifEjbPort引数を使用して構成できます。
wsifEjbBinding引数はejbAssembleまたはgenWsdlコマンドで使用して、単一のポートに対するWSIF EJBバインディングを指定できます。
wsifEjbBinding引数には、nameおよびjndiName引数を指定する必要があります。wsifEjbBinding引数により、これらの値はWSDLの<port>要素のejb:address要素に渡されます。jndiProviderURLおよびinitialContextFactory引数には、JNDIプロバイダURLおよびJNDI初期コンテキスト値があります。これらの引数を指定しない場合、これらの値はjndi.propertiesファイルから取得されます。
|
関連資料: この引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「wsifEjbBinding」を参照してください。 |
例9-7に、wsifEjbBindingをコールするWebServicesAssemblerのgenWsdlコマンドラインを示します。例9-8には対応するAntタスクを示します。引数により、WSDLの<port>要素のejb:address要素に、className="oracle.demo.hello.HelloImpl"およびjndiName="HelloService2EJB"が移入されます。変数${additional.class.path}はクラスパスを表します。
例9-7 wsifEjbBindingを使用して単一のEJBポートを構成するコマンドライン
java -jar wsa.jar -genWsdl
-output wsdl
-style rpc
-use literal
-wsifEjbBinding true
-jndiName HelloService2EJB
-interfaceName oracle.demo.ejb.HelloServiceInf
-jndiProviderUrl deployer:oc4j:localhost:23791/HelloService
-initialContextFactory oracle.j2ee.rmi.RMIInitialContextFactory
-className oracle.demo.hello.HelloImpl
-classpath ${additional.class.path}:build/classes
例9-8 wsifEjbBindingを使用して単一のEJBポートを構成するAntタスク
<oracle:genWsdl
output="wsdl"
style="rpc"
use="literal"
wsifEjbBinding="true"
jndiName="HelloService2EJB"
jndiProviderUrl="deployer:oc4j:localhost:23791/HelloService"
initialContextFactory="oracle.j2ee.rmi.RMIInitialContextFactory"
>
<oracle:porttype
interfaceName="oracle.demo.ejb.HelloServiceInf"
className="oracle.demo.hello.HelloImpl">
</oracle:porttype>
<oracle:classpath>
<pathelement path="${additional.class.path}"/>
<pathelement location="build.ejb.dir"/>
</oracle:classpath>
</oracle:genWsdl>
次に、このコマンドラインおよびAntタスクの例の説明をします。
genWsdl: Javaインタフェースを使用してボトムアップ方式でWebサービスをアセンブルするWSDLおよびJAX-RPCマッピング・ファイルを生成します。
output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。
style: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のstyle属性を指定します。
use: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のuse属性を指定します。
wsifEJBBinding: ボトムアップ方式でのWebサービス・アセンブリで使用し、WSIF EJBバインディングをWSDLに追加します。trueの場合、EJBのホーム・インタフェースclassNameおよびjndiNameも指定する必要があります。
jndiName: EJBのJNDI名を指定します。
jndiProviderUrl: JNDIプロバイダのURLを指定します。この引数は、wsifEjbBindingまたはwsifEjbPortでEJB WSIFポートを構成する際に、genWsdlまたはejbAssembleコマンドによってコールできるオプションの引数です。
porttype: このタグにより、異なるインタフェースをWebサービスに構成できます。
initialContextFactory: 初期コンテキストを提供するファクトリの名前を指定します。この引数は、wsifEjbBindingまたはwsifEjbPortでEJB WSIFポートを構成する際に、genWsdlまたはejbAssembleコマンドによってコールできるオプションの引数です。
interfaceName: サービス・エンドポイント・インタフェース(SEI)を含むJavaクラス名(パッケージ名を含みます)を指定します。
className: Webサービスの実装クラスであるクラス名(パッケージ名を含みます)を指定します。
classpath: WebServicesAssemblerに指定されるすべてのユーザー作成クラスを含むクラスパスを指定します。作成済の値タイプ・クラスまたは例外があり、WebServicesAssemblerで上書きしたくない場合に、この引数を指定します。
|
関連資料: これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。 |
wsifEjbPort引数はAntタスクでのみ使用できます。通常wsifEjbPortは、複数のポートにWSIF EJBバインディングを指定する際に使用しますが、単一のポートの指定に使用することもできます。引数には、WSIFポート名、クラス名、JNDI名、JNDI初期コンテキスト、および各ポートのJNDIプロバイダURLの指定を可能にする属性があります。これらの属性は、WSDLのejb:address要素に渡されます。表9-2に、wsifEjbPort引数で使用される属性を説明します。jndiNameを除き、属性はすべてオプションです。
表9-2 wsifEjbPort引数の属性
| 属性 | 説明 |
|---|---|
|
EJBのホーム・インタフェースのクラス名前を指定します。この属性に値を指定しない場合、WebServicesAssemblerは親Antタスクのクラス名を使用します(親Antタスクが指定されている場合)。 |
|
|
初期コンテキストを提供するファクトリの名前を指定します。この属性に値を指定しなかった場合は、 |
|
|
EJBのJNDI名を指定します(必須)。 |
|
|
JNDIプロバイダのURLを指定します。この属性に値を指定しなかった場合は、 |
|
|
WebサービスのWSIFポートの名前を指定します。この名前は、WSDLの |
例9-9のgenWsdlのAntタスクにより、WSDLのバインディング、バインディング操作およびポート句にWSIF EJBバインディング・コードが挿入されます。wsifEJBPort引数のclassName属性として使用されるHelloHomeクラスには、String型のgreetingパラメータを使用するsayHelloメソッドが含まれます。変数${additional.class.path}はクラスパスを表します。
例9-9 wsifEjbPortを使用した単一のEJBポートの構成
<oracle:genWsdl
output="wsdl"
style="rpc"
use="literal"
serviceName="${app.name}"
>
<oracle:porttype
interfaceName="oracle.test.wsif.HelloServiceInf">
<oracle:wsifEjbPort name="EjbPort"
className="oracle.test.wsif.HelloHome"
jndiName="HelloServiceBean"
jndiProviderUrl="deployer:oc4j:localhost:23791/HelloService"
initialContextFactory="oracle.j2ee.rmi.RMIInitialContextFactory"
/>
</oracle:porttype>
<oracle:classpath>
<oracle:pathelement path="${additional.class.path}"/>
<oracle:pathelement location="build/classes"/>
</oracle:classpath>
</oracle:genWsdl>
次に、このコマンドラインおよびAntタスクの例の説明をします。
genWsdl: Javaインタフェースを使用してボトムアップ方式でWebサービスをアセンブルするWSDLおよびJAX-RPCマッピング・ファイルを生成します。
output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。
style: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のstyle属性を指定します。
use: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のuse属性を指定します。
serviceName: サービス名を指定します。
porttype: このタグにより、異なるインタフェースをWebサービスに構成できます。
interfaceName: サービス・エンドポイント・インタフェース(SEI)を含むJavaクラス名(パッケージ名を含みます)を指定します。
wsifEJBPort: 複数のポートにWSIF Javaバインディングを指定できます。
className: Webサービスの実装クラスであるクラス名(パッケージ名を含みます)を指定します。
jndiName: EJBのJNDI名を指定します。
jndiProviderUrl: JNDIプロバイダのURLを指定します。この引数は、wsifEjbBindingまたはwsifEjbPortでEJB WSIFポートを構成する際に、genWsdlまたはejbAssembleコマンドによってコールできるオプションの引数です。
initialContextFactory: 初期コンテキストを提供するファクトリの名前を指定します。この引数は、wsifEjbBindingまたはwsifEjbPortでEJB WSIFポートを構成する際に、genWsdlまたはejbAssembleコマンドによってコールできるオプションの引数です。
classpath: WebServicesAssemblerに指定されるすべてのユーザー作成クラスを含むクラスパスを指定します。作成済の値タイプ・クラスまたは例外があり、WebServicesAssemblerで上書きしたくない場合に、この引数を指定します。
|
関連資料: これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。 |
例9-10に、前述の例でWSDLのバインディング、バインディング操作およびポート句に挿入された、WSIF EJBバインディング・コードを示します。
例9-10 WSIF EJBバインディングのWSDL拡張
... <ejb:binding/> <format:typeMapping encoding="Java" style="Java"> <format:typeMap typeName="xsd:string" formatType="java.lang.String"/> </format:typeMapping> ... <operation name="sayHello"> <ejb:operation methodName="sayHello" interface="remote" parameterOrder="greeting" returnPart="result"/> ... <port name="EjbPort" binding="tns:EjbPortBinding"> <ejb:address className="oracle.test.wsif.HelloHome" jndiName="HelloServiceBean" initialContextFactory="oracle.j2ee.rmi.RMIInitialContextFactory" jndiProviderURL="deployer:oc4j:localhost:23791/HelloService"/> </port> ...
複数のEJBポートにWSIFバインディングを定義するには、wsifEjbPort引数を使用します。この引数は、ejbAssembleおよびgenWsdl Antタスクで使用されます。例9-11に、EjbPortという名前のWSIFポート、およびSoapPortという名前のSOAPポートを作成するAntタスクを示します。SOAPポートは、<oracle:port name="... "/>サブタスクを追加することで作成されます。変数${additional.class.path}はクラスパスを表します。表9-2に、wsifEjbPortで使用される属性を説明します。
例9-11 wsifEjbPortを使用した複数のEJBポートの構成
<oracle:genWsdl
output="wsdl"
style="rpc"
use="literal"
serviceName="${app.name}"
>
<oracle:porttype interfaceName="oracle.test.wsif.HelloServiceInf"
>
<oracle:port name="SoapPort" uri="TestWsdlService"/>
<oracle:wsifEjbPort name="EjbPort"
className="oracle.test.wsif.HelloHome"
jndiName="HelloServiceBean"
jndiProviderUrl="deployer:oc4j:localhost:23791/HelloService"
initialContextFactory="oracle.j2ee.rmi.RMIInitialContextFactory"
/>
</oracle:porttype>
<oracle:classpath>
<oracle:pathelement path="${additional.class.path}"/>
<oracle:pathelement location="build/classes"/>
</oracle:classpath>
</oracle:genWsdl>
WSIFフレームワーク定義に準拠するために、OracleAS Web ServicesはEJBをWebサービスとして表現できるコードをWSDLに挿入します。例9-10に、その他のバインディング、バインディング操作およびポート句をWSDLに追加してWSIFサービスを記述する方法を示します。例9-12には、それらの拡張の対応するXMLスキーマ定義を示します。
例9-12 WSIF EJBバインディングをサポートするためのスキーマ定義
... <!-- EJB binding --> <binding ... > <ejb:binding/> <format:typeMapping style="uri" encoding="..."/>? <format:typeMap typeName="qname"|elementName="qname" formatType="nmtoken"/>* </format:typeMapping> ... <operation>* <ejb:operation methodName="nmtoken" parameterOrder="nmtoken"? returnPart="nmtoken"? interface="home|remote"? />? <input name="nmtoken"? />? <output name="nmtoken"? />? <fault name="nmtoken"? />? </operation> </binding> ... <service ... > <port>* <ejb:address className="nmtoken" jndiName="nmtoken" initialContextFactory="nmtoken"? jndiProviderURL="url"? /> </port> </service> ...
WSDLにデータベース・リソースのWSIF拡張を挿入するために、OracleAS Web Servicesには、WebServicesAssemblerのaqAssemble、dbJavaAssemble、plsqlAssemble、sqlAssembleおよびgenWsdlコマンドとともに使用できる2つの引数が用意されています。
wsifDbBinding
wsifDbPort
aqAssemble、dbJavaAssemble、plsqlAssemble、sqlAssembleまたはgenWsdlコマンドを使用してデータベース・リソースに基づいてWebサービスをアセンブル際には、wsifDbBindingおよびwsifDbPort引数を使用すると、WSIFバインディングを利用することでデータベースに直接起動を作成できます。データベースのWSIFクライアントでは、実行時にデータベースへの接続用のデータソースを決定できるJNDI設定を指定する必要があることに注意してください。
これらの引数により、Webサービスとして公開されているデータベース・リソースへのWSIFクライアントによるアクセスを可能にする適切なWSDL拡張が追加されます。
単一のポートにWSIFデータベース・リソース・バインディングを構成する際には、wsifDbBindingまたはwsifDbPort引数を使用できます。複数のポートに対してWSIFデータベース・リソース・バインディングを構成するには、wsifDbPort引数を使用する必要があります。
wsifDbBinding引数はコマンドラインまたはAntタスクで使用できますが、wsifDbPortはAntタスクでのみ使用できます。
次の項では、単一および複数のデータベース・リソース・ポートに対するWSIFエンドポイントの構成方法を説明します。
単一のデータベース・リソース・ポートに対するWSIFエンドポイントは、wsifDbBindingまたはwsifDbPortを使用して構成できます。
wsifDbBinding引数は、WebServicesAssemblerのaqAssemble、dbJavaAssemble、plsqlAssemble、sqlAssembleおよびgenWsdlコマンドとともに使用して、単一のポートにWSIFデータベース・リソース・バインディングを指定することができます。
データベース接続を確立するには、dataSource、またはdbUserおよびdbConnectionの組合せを指定する必要があります。
表9-3 wsifDbBindingおよびwsifDbPort引数の属性
| 属性 | 説明 |
|---|---|
|
Oracle JPublisherによって生成されたJavaクラスの名前を指定します(必須)。この属性に値を指定しない場合は、WebServicesAssemblerによりポート名に基づいて値が導出されます。 |
|
|
Webサービスによって使用されるデータソースのJNDIロケーションを指定します。この属性は、 |
|
|
データベースのJDBC URLを指定します。 この属性の詳細は、『Oracle Application Server Web Services開発者ガイド』の「データベース・アセンブリ引数」の項の「 |
|
|
user/passwordの形式でデータベースのスキーマとパスワードを指定します。この属性値は、データベースにアクセスするコード生成の際にのみ、使用します。
|
|
|
ポート名を指定します( |
AntタスクまたはコマンドラインでdataSource引数を使用すると、アセンブリ時および実行時にデータベースにアクセスできます。
AntタスクまたはコマンドラインでdbConnectionおよびdbUser引数を使用すると、アセンブリ時にデータベースにアクセスできます。また、dbConnection属性が実行時に使用されます。実行時のユーザー名およびパスワードの設定方法の詳細は、「WSIFクライアントからのデータベースへのアクセス方法」で説明されています。
AntタスクまたはコマンドラインでdbConnection、dbUserおよびdataSource引数を使用すると、dbConnectionおよびdbUserはアセンブリ時のデータベースへのアクセスに使用されます。dataSource引数は、実行時のアクセスに使用されます。
例9-13に、データベース・リソースに単一のポートを構成するためにwsifDbBindingをコールするWebServicesAssemblerのsqlAssembleコマンドラインを示します。例9-14には対応するAntタスクを示します。これらの例では、WSDLの<port>要素に入力されるdbUserおよびdbConnectionの値が指定されています。useDataSource引数がfalseに指定されている場合、dataSource引数の値はWSDLの<port>要素に使用されません。変数${wsdemo.common.class.path}、${additional.class.path}および${service.classes.dir}はクラスパス要素を表します。
例9-13 wsifDbBindingを使用して単一のデータベース・リソース・ポートを構成するコマンドライン
java -jar wsa.jar -sqlAssemble
-dbUser scott/tiger
-dbConnection jdbc:oracle:thin:@...
-dataSource jdbc/OracleManagedDS
-appName SqlWsifTest
-serviceName sqlwsif
-output build
-ear dist/SqlWsifTest.ear
-style rpc
-use literal
-wsifDbBinding true
-sqlstatement "getEname=select ename from emp"
-sqlstatement "updateSal=update emp SET sal=sal+500 where
ename=:{myname VARCHAR}"
-classpath ${CLASSPATH}:build/classes
例9-14 wsifDbBindingを使用して単一のデータベース・リソース・ポートを構成するAntタスク
<oracle:sqlAssemble
dbUser="scott/tiger"
dbConnection="jdbc:oracle:thin@…"
dataSource="jdbc/OracleManagedDS"
appName="SqlWsifTest"
serviceName="sqlwsif"
output="build"
ear="dist/SqlWsifTest.ear"
style="rpc"
use="literal"
wsifDbBinding="true"
>
<oracle:port name="sqlwsif" uri="SqlWsifTest" />
<sqlstatement value="getEname=select ename from emp" />
<sqlstatement value="updateSal=update emp SET sal=sal+500 where ename=:{myname VARCHAR}" />
<oracle:classpath>
<oracle:pathelement path="${wsdemo.common.class.path}"/>
<oracle:pathelement path="${additional.class.path}"/>
<oracle:pathelement location="client/classes"/>
<oracle:pathelement location="${service.classes.dir}"/>
</oracle:classpath>
</oracle:sqlAssemble>
次に、このコマンドラインおよびAntタスクの例の説明をします。
sqlAssemble: SQL問合せおよびDML(データ操作言語)を含むSQL文からWebサービスを生成します。このコマンドを使用するには、データベースに接続している必要があります。
dbUser: user/passwordの形式でデータベースのスキーマとパスワードを指定します。
dbConnection: データベースのJDBC URLを指定します。
dataSource: 実行時にWebサービスによって使用されるデータソースのJNDIロケーションを指定します。
appName: アプリケーション名を指定します。通常、この名前はcontextおよびuriなどの他の引数のベース値として使用されます。
serviceName: サービス名を指定します。
output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。
ear: 生成されたEARの名前および場所を指定します。
style: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のstyle属性を指定します。
use: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のuse属性を指定します。
wsifDbBinding: ボトムアップ方式でのWebサービス・アセンブリで使用し、WSIF SQLバインディングをWSDLに追加します。WebServicesAssemblerにより、WSDLに、SOAPバインディングおよびネイティブWSIF SQLバインディングが生成されます。
sqlStatement: Webサービスとして公開されるDML文またはSQL問合せを指定します。
classpath: WebServicesAssemblerに指定されるすべてのユーザー作成クラスを含むクラスパスを指定します。作成済の値タイプ・クラスまたは例外があり、WebServicesAssemblerで上書きしたくない場合に、この引数を指定します。
|
関連資料: これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。 |
例9-15に、前述の例でWSDLの<port>要素に挿入された、WSIFデータベース・リソース・バインディング・コードを示します。
wsifDbPort 引数はAntタスクでのみ使用できます。通常wsifDbPortは、複数のポートにWSIFデータベース・リソース・バインディングを指定する際に使用しますが、単一のポートの指定に使用することもできます。引数には、WSIFポート名、Oracle JPublisherによって生成されたJavaファイルのクラス名、およびデータベース接続情報の指定を可能にする属性があります。これらの引数は、WSDLの<port>要素のjava:address要素に渡されます。
表9-3に、wsifDbPort引数で使用される属性を説明します。classNameおよびnameを除き、属性はすべてオプションです。
AntタスクまたはコマンドラインでdataSource引数を使用すると、アセンブリ時および実行時にデータベースにアクセスできます。
AntタスクまたはコマンドラインでdbConnectionおよびdbUser引数を使用すると、アセンブリ時にデータベースにアクセスできます。また、dbConnection属性が実行時に使用されます。実行時のユーザー名およびパスワードの設定方法の詳細は、「WSIFクライアントからのデータベースへのアクセス方法」で説明されています。
AntタスクまたはコマンドラインでdbConnection、dbUserおよびdataSource引数を使用すると、dbConnectionおよびdbUserはアセンブリ時のデータベースへのアクセスに使用されます。dataSource引数は、実行時のアクセスに使用されます。
例9-13に、WSDLのバインディング、バインディング操作およびポート句にWSIFデータベース・リソース・コードを挿入する、WebServicesAssemblerのwsifDbPortコマンドラインを示します。例9-16には対応するAntタスクを示します。wsifDbPort引数では、ポート名はJavaPortに設定され、JPublisherによって生成されたJavaクラスの名前はoracle.generated.sqlwsifUserに設定されています。
例9-16 wsifDbPortを使用して単一のデータベース・リソース・ポートを構成するAntタスク
<oracle:sqlAssemble
dataSource="jdbc/OracleManagedDS"
appName="SqlWsifTest"
portName="sqlwsif"
serviceName="sqlwsif"
output="build"
ear="dist/SqlWsifTest.ear"
style="rpc"
use="literal"
>
<oracle:port name="sqlwsif" uri="SqlWsifTest" />
<sqlstatement value="getEname=select ename from emp" />
<sqlstatement value="updateSal=update emp SET sal=sal+500 where ename=:{myname VARCHAR}" />
<oracle:wsifDbPort
name="JavaPort"
className="oracle.generated.sqlwsifUser"
/>
<oracle:classpath>
<oracle:pathelement path="${wsdemo.common.class.path}"/>
<oracle:pathelement path="${additional.class.path}"/>
<oracle:pathelement location="client/classes"/>
<oracle:pathelement location="service/classes"/>
</oracle:classpath>
</oracle:sqlAssemble>
例9-17に、前述の例でWSDLに挿入された、WSIFデータベース・リソース・バインディング・コードを示します。
複数のデータベース・リソース・ポートにWSIFバインディングを定義するには、wsifDbPort引数を使用します。この引数は、AntタスクのaqAssemble、dbJavaAssemble、plsqlAssemble、sqlAssembleおよびgenWsdlコマンドで使用されます。
例9-18に、SOAPポートおよびWSIFポートを作成するAntタスクを示します。ポート操作は、<sqlstatement value="..."/>サブタスクに基づいています。wsifDbPortサブタスクは、JavaPortポートを作成します。oracle:portサブタスクは、SOAPポートを作成します。変数${wsdemo.common.class.path}、${additional.class.path}および${service.classes.dir}はクラスパス要素を表します。表9-3に、wsifDbPortで使用される属性を説明します。
例9-18 wsifDbPortを使用して複数のデータベース・リソース・ポートを構成するAntタスク
<oracle:sqlAssemble
dbUser="scott/tiger"
dbConnection="jdbc:oracle:thin:@${DB_HOST}:${DB_PORT}:${DB_SID}"
dataSource="jdbc/OracleManagedDS"
appName="wsifTest"
portName="dbwsif"
serviceName="dbwsif"
output="build"
ear="dist/wsifDbTest.ear"
style="rpc"
use="literal"
>
<oracle:port name="dbwsif" uri="wsifDbTest"/>
<sqlstatement value="getEname=select ename from emp" />
<sqlstatement value="updateSal=update emp SET sal=sal+500 where
ename=:{myname VARCHAR}" />
<oracle:wsifDbPort name="JavaPort"
className="oracle.generated.sqlwsifUser"
>
<oracle:classpath>
<oracle:pathelement path="${wsdemo.common.class.path}"/>
<oracle:pathelement path="${additional.class.path}"/>
<oracle:pathelement location="${client.classes.dir}"/>
<oracle:pathelement location="${service.classes.dir}"/>
</oracle:classpath>
</oracle:sqlAssemble>
次に、このAntタスクの例を説明します。
sqlAssemble: SQL問合せおよびDML(データ操作言語)を含むSQL文からWebサービスを生成します。このコマンドを使用するには、データベースに接続している必要があります。
dbUser: user/passwordの形式でデータベースのスキーマとパスワードを指定します。
dbConnection: データベースのJDBC URLを指定します。
dataSource: 実行時にWebサービスによって使用されるデータソースのJNDIロケーションを指定します。
appName: アプリケーション名を指定します。通常、この名前はcontextおよびuriなどの他の引数のベース値として使用されます。
portName: WSDLドキュメントのポートの名前を指定します。
serviceName: サービス名を指定します。
output: 生成されたファイルを保存するディレクトリを指定します。ディレクトリが存在しない場合に作成されます。
ear: 生成されたEARの名前および場所を指定します。
style: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のstyle属性を指定します。
use: ボトムアップ方式でのWebサービス・アセンブリでは、この引数は生成されたWSDLでメッセージ書式のuse属性を指定します。
wsifDbPort: 複数のデータベース・リソース・ポートにWSIFバインディングを定義できます。
sqlStatement: Webサービスとして公開されるDML文またはSQL問合せを指定します。
classpath: WebServicesAssemblerに指定されるすべてのユーザー作成クラスを含むクラスパスを指定します。作成済の値タイプ・クラスまたは例外があり、WebServicesAssemblerで上書きしたくない場合に、この引数を指定します。
|
関連資料: これらの引数の詳細は、『Oracle Application Server Web Services開発者ガイド』の「WebServicesAssemblerの使用方法」を参照してください。 |
WSIFフレームワーク定義に準拠するために、OracleAS Web Servicesはデータベース・リソースをWebサービスとして表現できるコードをWSDLに挿入します。例9-15に、追加のデータベース・リソース・バインディングをどのようにWSDLに配置するかを示します。具体的には、WSIFのJavaPortBindingがオプションのdataSource属性を使用してさらに拡張されています。この属性が存在する場合、Javaポートではなくデータベース・ポートであることを意味します。例9-19に、この拡張の対応するXMLスキーマ定義を示します。
例9-19 WSIFデータベース・リソース・バインディングをサポートするためのスキーマ定義
...
<definitions .... >
<!-- Java binding -->
<binding ... >
<java:binding/>
<format:typeMapping style="uri" encoding="..."/>?
<format:typeMap typeName="qname"|elementName="qname" formatType="nmtoken"/>*
</format:typeMapping>
<operation>*
<java:operation
methodName="nmtoken"
parameterOrder="nmtoken"?
returnPart="nmtoken"?
methodType="instance|static|constructor"? />?
<input name="nmtoken"? />?
<output name="nmtoken"? />?
<fault name="nmtoken"? />?
</operation>
</binding>
<service ... >
<port>*
<java:address
className="nmtoken"
classPath="nmtoken"?
classLoader="nmtoken"?
dataSource="nmtoken"?
</port>
</service>
</definitions>
...
WSIFクライアントは、事前生成済のスタブに依存しない点でDIIクライアントに似ています。WSIFクライアントでは、WSDLが重要な役割を果します。WSDLにはサービスを起動するすべての情報が含まれているため、クライアントが実行時に使用できる必要があります。WSIFクライアントでは、メッセージを使用して実際に操作を起動する前に、WSIFサービス、ポート、操作およびメッセージを作成する必要があります。
WSIF APIは、WSDLのサービスの要約説明部分に基づいており、WSDLからその情報を取得するためのメソッドが含まれています。WSIF APIは、Apache Software FoundationのWebサイトから入手できます。
|
注意: WebServicesAssemblerでは、WSIFクライアントの生成はサポートされていません。 |
この項の内容は、次のとおりです。
WSIFクライアントを記述するには、次の一般的な手順に従います。
WSIFサービス・ファクトリの新しいインスタンスを作成します。
org.apache.wsif.WSIFServiceFactoryクラスのnewInstanceメソッドにより、新規のWSIFサービス・ファクトリが初期化されます。次に例を示します。
// create a service factory WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
WSIFサービスを作成します。
WSDLファイルの情報が、WSIFサービスの作成に使用されます。WSIFServiceFactoryクラスには、WSDLからサービス定義を取得するための様々なgetServiceメソッドがあります。WSDLファイルの場所は、HTTPを介して取得可能なURLの場所、またはclassLoaderを介して取得可能なファイルベースの場所として指定されます。サービスを作成するためのその他のパラメータは、サービス名/名前空間およびportType/名前空間です。次に例を示します。
WSIFService service = factory.getService( ... );
WSIFポート、操作およびメッセージを作成します。
WSIFサービスを使用してWSIFポートを作成します。WSIF APIのWSIFService.getPortメソッドのいずれかを使用して、このファクトリでサポートされているポート・タイプのWSIFポートを取得します。次に例を示します。
WSIFPort port = service.getPort("portName");
WSIF操作を作成します。
WSIFポートを使用してWSIF操作を作成します。操作は、サービス名、またはサービス名および入力と出力メッセージの組合せを使用して作成されます。このポートのportTypeには、この名前の操作が必ず1つ存在する必要があります。WSIF APIでは、Webサービスとして公開しているJ2EEコンポーネントの種類に応じて、様々なcreateOperationメソッドがサポートされています。次に例を示します。
WSIFOperation operation = port.createOperation("operationName");
入力、出力および障害メッセージを作成します。
WSIF操作を使用してメッセージを作成します。WSIF APIのWSIFOperationインタフェースでは、入力、出力および障害メッセージを作成するための様々なメソッドがサポートされています。次に例を示します。
WSIFMessage input = operation.createInputMessage(); WSIFMessage output = operation.createOutputMessage(); WSIFMessage fault = operation.createFaultMessage();
入力メッセージを移入します。
RPC起動またはdocument-literalWebサービス起動のどちらを使用するかにより、メッセージを移入する方法が2つ考えられます。
RPC Webサービスに入力メッセージを移入するには、入力メッセージのpart(WSDLで定義済)を設定します。たとえば、WSIFMessage.setObjectPartメソッドのいずれか1つを使用して、操作からサービスに値を渡せるようにします。また、サービスによって設定されている型マップに基づくJavaクラスを使用して、メッセージ・タイプを設定できます。次の例では、name変数を操作のWSDLのリクエスト・メッセージ部分から取得します。
input.setObjectPart("name", "Duke");
document-literal Webサービスに入力メッセージを移入する場合は、クライアントでpartを設定する前にSOAPElementオブジェクトを構成する必要があります。これは、次の例に示されています。ここでは、parameter変数を、sayHello操作のWSDLのリクエスト・メッセージ部分から取得します。
SOAPFactory soapfactory = SOAPFactory.newInstance();
SOAPElement request = soapfactory.createElement("sayHelloElement", "ns0",
"http://oracle.demo.hello/");
SOAPElement nameChild = soapfactory.createElement("name");
nameChild.addTextNode("Duke");
request.addChildElement(nameChild);
input.setObjectPart("parameter", request)
サービスへのコールを作成します。
WSIF APIのいずれかのexecuteメソッドを使用して操作を実行します。シグネチャにより、入力、出力および障害メッセージが許可されます。WSIF APIでは、Webサービスとして公開しているJ2EEコンポーネントの種類に応じて、様々なexecuteメソッドがサポートされています。次に例を示します。
operation.executeRequestResponseOperation( ... );
このコールにより、操作が成功するとtrueと等価のブール変数が戻されます。それ以外の場合はfalseが戻されます。コールが失敗すると、失敗の原因を特定するために障害メッセージが調査されます。障害メッセージは、SOAP仕様に定義されているSOAPBody:Fault要素に基づいて移入されます。コールが成功すると、(入力メッセージの移入と同様に)出力メッセージ部分に基づいて、出力メッセージの内容がJavaクラスに抽出されます。
例9-20に、DIIクライアントのサンプルを示します。クライアントは、HelloServiceのsayHelloメソッドで起動を実行し、nameパラメータの値としてDukeを渡しています。サービスを定義するWSDLは、http://localhost:8888/helloWSIFDii/helloWSIFDii?WSDLでデプロイされています。portTypeはQName {http://hello.demo.oracle/}HelloInterfaceです。ここで、http://hello.demo.oracle/はportType名前空間で、HelloInterfaceはポート名です。WSIFポートの名はHelloServicePortで、操作の名前はsayHelloです。executeRequestResponseOperationメソッドによりサービスへのコールが作成されます。
例9-20 WSIFクライアント・コードのサンプル
import org.apache.wsif.*;
...
// create a service factory
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
// parse the WSDL
WSIFService service =
factory.getService("http://localhost:8888/helloWSIFDii/helloWSIFDii?WSDL",
null, null, "http://hello.demo.oracle/", "HelloInterface");
// create WSIF port, operation, and messages
WSIFPort port = service.getPort("HelloServicePort");
WSIFOperation operation = port.createOperation("sayHello");
WSIFMessage input = operation.createInputMessage();
WSIFMessage output = operation.createOutputMessage();
WSIFMessage fault = operation.createFaultMessage();
input.setObjectPart("name", "Duke");
// make the actual call to the service
operation.executeRequestResponseOperation(input, output, fault);
...
さらに簡単にWSIFクライアントを記述する方法は、サービス・エンドポイント・インタフェースを使用して記述する方法です。WSIFのランタイムにより、動的プロキシという形で対応する実装が作成されます。この方法では、すでにコンパイル済のサービス・エンドポイント・インタフェースがあることが想定されています。WSIF APIには、インタフェースを実装する動的プロキシを取得するgetStubメソッド(org.apache.wsif.WSIFService.getStub)があります。
次の手順では、動的プロキシとしてインタフェースを取得する方法をまとめます。
WSIFサービス・ファクトリの新しいインスタンスを作成します。
次に例を示します。
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
WSIFサービスを作成します。
次に例を示します。
WSIFService service = factory.getService( ... );
サービス・ポート名およびサービス・エンドポイント・インタフェース・クラスをgetStubメソッドに渡します。サービス・エンドポイント・インタフェースに戻された動的プロキシをキャストします。
次に例を示します。
HelloInterface stub = (HelloInterface) service.getStub( ... );
インタフェースを実装するプロキシでメソッドを直接コールします。
次に例を示します。
String resp = stub.sayHello("Duke");
例9-21に、WSIFクライアントを動的プロキシとして使用する例を示します。ポート名HttpSoap11およびサービス・エンドポイント・インタフェース・クラスHelloInterface.classは、getStubメソッドに渡されます。戻された動的プロキシは、HelloInterfaceサービス・エンドポイント・インタフェースにキャストされます。stubパラメータもHelloInterface型として宣言されていることに注意してください。スタブを使用すると、インタフェースでメソッドを直接コールできます。
例9-21 動的プロキシとしてのWSIFクライアントの使用
// Create a service factory
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
// Parse the WSDL
WSIFService service = factory.getService(serviceURL + "?WSDL", null, null,
"http://hello.demo.oracle/", "HelloInterface");
// Call the getStub method with the port name and
// the service endpoint interface class.
// Cast the returned dynamic proxy to the service endpoint interface.
HelloInterface stub = (HelloInterface) service.getStub("HttpSoap11", HelloInterface.class);
// Call methods directly on the interface
String resp = stub.sayHello("Duke");
前述の項の手順では、WSDLとサービス・エンドポイント・インタフェースがあることが前提とされていました。サービス・エンドポイント・インタフェースがない場合は、WSDLをガイドとして使用し、手動で記述して取得することが可能です。
インタフェースを手動で記述するかわりに、WSDLをWebServicesAssemblerのgenInterfaceコマンドに渡すこともできます。コマンドにより、サービス・エンドポイント・インタフェースが生成されます。WSDLにメソッドに変換する必要のある操作が多数ある場合には特に便利です。
genInterfaceによりWSDL操作がJavaメソッドに変換される際、メソッド名の最初の文字は必ず小文字になります。WSDLの元の操作名が大文字で始まる場合には、プロキシでメソッドのコールを試行する際に不一致の原因となります。通常、メソッドが存在しないというエラーが戻されます。
このエラーを回避するには、メソッド名がWSDLの操作名と文字ごとに正確に一致するように、必要な場合にはサービス・エンドポイント・インタフェースを編集します。
wsifDbBindingおよびwsifDBPort引数により、WSDLに適切なバインディングが追加されます。これにより、WSIFクライアントはWebサービスとして公開されているデータベース・リソースにアクセスできるようになります。dataSource引数は、リソースを含むデータベースを特定します。
コード生成時および実行時にデータベースURLを特定する際に、dataSource引数を省略し、dbConnectionのみを使用する場合、WebServicesAssemblerによりWSDLファイルにその値が生成されます。データベースにアクセスするには、WSIFクライアントは実行時にユーザー名およびパスワードの値を渡す必要があります。生成されたコードには、これを実行するためのメソッドが2つあります。
public void _setDataSourceUser(String); public void _setDataSourcePassword(String);
次に、これらのメソッドの完全なパスを示します。CLASSNAME変数は、className引数によって指定された値を表します。classNameが指定されていない場合は、デフォルトでportNameの値に設定されます。
CLASSNAME.setDataSourceUser(String user); CLASSNAME.setDataSourceUser(String password);
コマンドラインまたはAntタスクでdataSource引数を指定した場合には、これら2つのメソッドは不要です。クライアントには、すでにデータベースへのアクセス権があります。
例9-22に、例9-14でAntタスクによってアセンブルされたWebサービスのクライアントを示します。ユーザー名およびパスワードをサーバーに渡すsetDataSourceUserおよびsetDataSourcePasswordメソッドは、太字で強調してあります。
例9-22 ユーザー名およびパスワードをサービスに渡すクライアント・コード
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
WSIFService service = factory.getService(wsdlPath1, null, null,
"http://generated.oracle/", "sqlwsif");
oracle.generated.sqlwsif stub = null;
stub = (oracle.generated.sqlwsif)
service.getStub("JavaPort", oracle.generated.sqlwsif.class);
stub.setDataSourceUser("scott");
stub.setDataSourcePassword("tiger");
System.out.println("Run Sql...");
String[] names = stub.getEname();
セキュリティ、信頼性および監査に関するWebサービス管理構成をWSIFクライアントに追加できます。
WSIFクライアント上のWebサービス管理構成は、一致するWebサービス管理構成を持つSOAPポートまたは操作を起動する場合にのみ役立ちます。
OracleAS Web Servicesでは、Webサービス側のJavaおよびEJBポートのWebサービス管理構成をサポートしていません。
Webサービス管理構成のあるWSIFクライアントがJavaまたはEJBポートと通信する場合、Webサービス管理構成は無視されます。ただし、Webサービス管理は、SOAPポートがサービスの起動に使用されている場合に使用されます。
J2EE_HOME/config/wsif-wsm-config.xmlファイルには、クライアントの発信管理ポリシーを指定できるテンプレートが用意されています。wsif-wsm-config.xmlファイルはoracle-webservices-client-10_0.xsdスキーマに基づいています。
デフォルトでは、wsif-wsm-config.xmlファイルはJ2EE_HOME/configディレクトリに存在します。ファイル名を変更するか、別の場所からコールすると、wsif.wsm.config.fileシステム・プロパティを使用してデフォルトの名前や場所を上書きできます。
管理構成を作成し、WSIFクライアントで使用できるようにするには、次のいずれかの方法でwsif-wsm-config.xmlファイルを使用します。
J2EE_HOME/configディレクトリのwsif-wsm-config.xmlファイルを編集します。
wsif-wsm-config.xmlファイルをテンプレートとして使用し、選択した場所に保存します。次のシステム・プロパティを使用して、ファイルの新しい名前と場所を指定します。
-Dwsif.ws.config.file=<path to file>
例9-23に、wsif-wsm-config.xmlファイルの内容を示します。表9-4に、ファイルの要素を説明します。
例9-23 WSIFクライアントの構成ファイル
<?xml version="1.0" encoding="UTF-8"?>
<oracle-webservice-clients xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="/oracle-webservices-client-10_0.xsd">
<webservice-client>
<service-qname namespaceURI="" localpart=""/>
<port-info>
<wsdl-port namespaceURI="" localpart=""/>
<service-endpoint-interface></service-endpoint-interface>
<stub-property>
<name></name>
<value></value>
</stub-property>
<call-property>
<name></name>
<value></value>
</call-property>
<runtime>
<security>
<!--ポート・レベルのセキュリティ構成。セキュリティ構成要素の詳細は、『Oracle Application Server Web Servicesセキュリティ・ガイド』を参照してください。 -->
</security>
<reliability>
<!--ポート・レベルの信頼性構成。信頼性構成要素の説明は、「クライアントにおけるポート・レベルの信頼性要素」を参照してください。 -->
</reliability>
</runtime>
<operations>
<operation name="">
<runtime>
<security>
<!--操作レベルのセキュリティ構成。セキュリティ構成要素の詳細は、『Oracle Application Server Web Servicesセキュリティ・ガイド』を参照してください。 -->
</security>
<!--操作レベルの監査構成。監査構成要素の説明は、「J2EEクライアントにおける監査の構成方法」を参照してください。 -->
<auditing/>
<reliability>
<!--操作レベルの信頼性構成。信頼性構成要素の説明は、「クライアントにおける操作レベルの信頼性要素」を参照してください。 -->
</reliability>
</runtime>
</operation>
</operations>
</port-info>
</webservice-client>
</oracle-webservice-clients>
表9-4に、<port-info>要素のサブ要素を説明します。この要素は、サービス参照のポートの詳細を提供します。コンテナがコンテナ管理ポートの選択で使用するポートを、service-endpoint-interfaceまたはwsdl-portに指定します。両方を指定すると、wsdl-portの値が使用されます。wsdl-portやservice-endpoint-interfaceを指定しない場合は、<port-info>プロパティの値が、すべての使用可能なポートに対して適用されます。
また、<port-info>要素には、ポートおよびその操作に対して、使用可能なサービスのクオリティ機能を指定できるサブ要素も含めることができます。
表9-4 <port-info>要素のサブ要素
| 要素名 | 説明 |
|---|---|
|
|
|
|
操作ごとに要素を1つずつ指定した、一連の要素を指定します。個々の操作は、
|
|
|
参照先のWebサービスにより提供されるすべての操作に適用されるクライアント・サイドの、サービスのクオリティのランタイム情報(セキュリティまたは信頼性(あるいはその両方))を指定します。各機能の構成は、それぞれの子要素に指定します。 |
|
|
WSDLポートのサービス・エンドポイント・インタフェースの完全修飾パスを指定します。コンテナは、このポートをコンテナ管理ポートの選択に使用します。 |
|
|
|
|
|
コンテナによりコンテナ管理ポートの選択に使用されるWSDL内のポートの |
表9-5に、<stub-property>および<call-property>要素のnameおよびvalueサブ要素を説明します。
WSIFのDIIクライアントは、oracle.webservices.OracleCall、oracle.oc4j.wsif.providers.jaxrpc.WSIFPort_JaxRpcおよびWSIFOperationAPIのメソッドを使用して、HTTPリクエストおよびレスポンス・ヘッダーを取得できます。
レスポンス・ヘッダーを取得するには、WSIFOperation.executeRequestResponseOperationメソッドを使用してサービスを呼び出し、WSIFPort_JaxRpc.getCallメソッドでOracleCallオブジェクトを取得します。OracleCall.getResponseHeadersメソッドは、SOAPレスポンス・ヘッダーを含むVectorを戻します。
リクエスト・ヘッダーを取得するには、OracleCall.getHeadersメソッドを使用します。このメソッドも、要素がSOAPレスポンス・ヘッダーであるVectorを戻します。通常、ヘッダーはOracleCall.addHeadersメソッドでVectorに追加されます。
例9-24に、レスポンス・ヘッダーを取得するためのDIIクライアント・コードを示します。
例9-24 DIIクライアント・コードのレスポンス・ヘッダーの取得
...
operation.executeRequestResponseOperation(input, output, fault);
OracleCall call = (OracleCall) ((WSIFPort_JaxRpc) port).getCall();
Vector headers = call.getResponseHeaders();
if (Vector != null) {
for(int i = 0;i < headers.size();i++) {
Element header = (Element) headers.get(i);
// do something with the header Element
...
}
}
...
WSIFクライアントを有効化して、メッセージ添付ファイルを追加できます。デフォルトでは、WSIFはMIME書式メッセージで追加する添付ファイルをサポートします。添付ファイル自体は、javax.activation.DataHandlerタイプのオブジェクトで、mime:multipartRelated、mime:partおよびmime:contentタグを使用してWSDLの添付ファイルを記述します。
WSIFクライアントを有効化してメッセージに添付ファイルを追加するには、次の一般的な手順に従います。
DataHandlerオブジェクトを作成し、添付ファイルをカプセル化します。
WSIF APIのWSIFOperation.createInputMessageメソッドを使用して、対象の操作に入力メッセージを作成します。
WSIF APIのWSIFMessage.setObjectPartメソッドを使用して、メッセージに添付ファイルを追加します。
例9-25に、WSIF APIを使用してメッセージに添付ファイルを追加する方法を示します。コード・フラグメントでは、JohnDoe.jpg添付ファイルはDataHandlerオブジェクトとして保存されています。operationNameは、添付ファイル付きのメッセージを処理するために有効化される操作を表します。WSIFOperationのcreateInputMessageメソッドにより、操作に入力メッセージが作成されます。WSIFMessageのsetObjectPartメソッドにより、部分名がmyAttachmentの入力メッセージに添付ファイルが添付されます。
oracle.webservices.OracleCall APIを使用すると、WSIFクライアントによって処理されるメッセージに添付ファイルを追加できます。この方法を使用する場合は、添付ファイルをDataHandlerオブジェクトとして保存します。その後、WSIFポートから取得するDIIコール・オブジェクトに添付ファイルを追加します。
|
関連資料:
|
例9-26に、OracleCall APIを使用してメッセージに添付ファイルを追加する方法を示します。コード・フラグメントでは、JohnDoe.jpg添付ファイルはDataHandlerオブジェクトとして保存されています。getCallメソッドにより、WSIFポートからDIIコールが取得されます。このコールは、SOAPポートおよびOracleCallオブジェクトにキャストされている必要があります。OracleCall.addAttachmentメソッドにより、コール内のSOAPメッセージに添付ファイルが追加されます。addAttachmentメソッドを使用すると、添付ファイルのMIMEパートのcontent-transfer-encodingおよびcontent-IDを直接設定できることに注意してください。
WSIFクライアントでは、OracleCallおよびAttachments APIのメソッドを使用して、サービスからストリーミング添付ファイルを取得できます。
|
関連資料:
|
例9-27に、サーバーからストリーム・レスポンス添付ファイルを取得するためのWSIFクライアント・コードのサンプルを示します。この例では、getCallメソッドにより、WSIFポートからDIIコールが取得されます。このコールは、SOAPポートおよびOracleCallオブジェクトにキャストされている必要があります。executeRequestResponseOperationメソッドによりサービスへのコールが作成されます。OracleCall.getStreamedResponseAttachmentsメソッドは、OracleCallオブジェクトからストリーミング添付ファイルを取得します。getIncomingAttachmentsメソッドは、受信ストリーミング添付ファイルをAttachmentオブジェクトとして取得します。whileループは、incomingAtts IncomingAttachmentsオブジェクトを繰り返します。getDataHandlerメソッドは、Attachmentオブジェクトからデータ・ハンドラを取得し、添付ファイルを入力ストリーム(getInputStream)として取得します。
例9-27 ストリーム・レスポンスを取得するWSIFクライアント・コード
...
OracleCall call = (OracleCall) ((WSIFPort_JaxRpc) port).getCall();
operation.executeRequestResponseOperation(input, output, fault);
Attachments atts = call.getStreamedResponseAttachments();
IncomingAttachments incomingAtts = atts.getIncomingAttachments();
while (incomingAtts.hasNextAttachment()) {
Attachment att = incomingAtts.nextAttachment();
InputStream is = att.getDataHandler().getInputStream();
// read from InputStream is until no byte to read
...
}
デフォルトでは、DIIおよびWSIF APIクライアントで送信するメッセージの添付ファイルは、MIMIE書式でパッケージ化されます。メッセージ添付ファイル・パッケージをDIME書式で送信するには、WSIFメッセージ・コンテキストでブール型プロパティWSIFConstants.DIME_PACKAGINGをtrueに設定します。このプロパティは、setBooleanPartメソッドを使用したコンテキストで設定できます。
プロパティをfalse(デフォルト)に設定するか、使用しない場合、WSIFメッセージ添付ファイルはMIME書式でパッケージされます。
例9-28に、DIME_PACKAGINGプロパティの使用方法を示します。この例では、WSIFMessage型の新しいcontextオブジェクトが作成され、DIME_PACKAGINGプロパティが適用されます。コンテキストは、operationに適用されます。メッセージに追加されたすべての添付ファイルは、DIME書式で追加されます。例で使用するoperationオブジェクトは、WSIFOperationのインスタンスです。
Oracle JDeveloperのJavaクラス用のJava J2EE Webサービス・ウィザードを使用すると、WebサービスのSOAPバインディングのみでなくWSIFバインディングも作成できます。クラス・ローダーおよびクラスパスの値を入力します。これにより、WSIFクライアントがサービス実装クラスを検出できるようになります。これらの値は、コマンドラインまたはAntタスクのclassLoaderおよびclassPathパラメータに相当します。
EJB用のWebサービス・ウィザードを使用すると、初期コンテキスト・ファクトリ、JNDIプロバイダURLおよびJNDI名を指定でき、WSIFクライアントがJNDIを介してEJBを検出できるようになります。これらの値は、コマンドラインまたはAntタスクのinitialContextFactory、jndiProviderUrlおよびjndiNameパラメータに相当します。
データベースWebサービス・ウィザードを使用すると、ユーザー、接続、およびPL/SQLプロシージャにWSIFバインディングを定義する際に必要なデータソース情報を指定できます。
詳細は、次を参照してください。
メッセージ添付ファイルを使用する場合は、第2章「メッセージ添付ファイルの処理」を参照してください。
Webサービスに管理構成を追加する場合は、第3章「Webサービスの管理」を参照してください。
Webサービスにセキュリティ情報を追加する場合は、第4章「Webサービスのセキュリティの確保」および『Oracle Application Server Web Servicesセキュリティ・ガイド』を参照してください。
Webサービスに信頼性のある情報を追加する場合は、第5章「Webサービスの信頼性の確保」を参照してください。
セキュリティ構成を含むwsmgmt.xmlファイルの内容については、付録A「Webサービス管理スキーマの概要」を参照してください。
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の使用方法」を参照してください。