| Oracle® Fusion Middleware Oracle WebLogic Server JAX-RPC Webサービス・スタート・ガイド 11gリリース1 (10.3.6) B61647-06 |
|
![]() 前 |
![]() 次 |
この章では、Java API for XML-based RPC (JAX-RPC)を使用してWebLogic Webサービスを呼び出す方法について説明します。
この章では、以下のトピックについて説明します。
|
注意: 以降の項では、メッセージ保護されたWebサービスの呼出しについては説明していません。そのトピックについては、『Oracle Fusion Middleware Oracle WebLogic Server WebLogic Webサービスの保護』のクライアント・アプリケーションの更新によるメッセージ保護されたWebサービスの呼出しに関する項を参照してください。 |
Webサービスの呼出しは、クライアント・アプリケーションがWebサービスを使用するために実行するアクションです。Webサービスを呼び出すクライアント・アプリケーションは、Java、Microsoft .NETなどの任意のテクノロジを使用して記述できます。
クライアント・アプリケーションには以下の2種類があります。
Java SEクライアント: 最も単純な形態では、Java SEクライアントは、javaコマンドで呼び出されるMainパブリック・クラスを持つJavaプログラムです。
WebLogic ServerにデプロイされたJava EEコンポーネント: このタイプのクライアント・アプリケーションでは、EJB、サーブレット、または別のWebサービスなど、WebLogic ServerにデプロイされているJava Platform, Enterprise Edition (Java EE)バージョン5コンポーネント内でWebサービスが実行されます。したがって、このタイプのクライアント・アプリケーションはWebLogic Serverコンテナの内部で実行されます。
WebLogic Serverで実行されている(WebLogic Serverクラスパスにアクセスする)任意のJava SEまたはJava EEアプリケーションからWebサービスを呼び出すことができます。WebLogic Serverのライブラリにアクセスできない環境で実行されているスタンドアロンJavaアプリケーションのサポートについての詳細は、「Webサービス呼出し時のスタンドアロン・クライアントJARファイルの使用」を参照してください。
以降の項では、JAX-RPC仕様のOracleの実装を使用してJavaクライアント・アプリケーションからWebサービスを呼び出す方法について説明します。この実装を使用することで、WebLogicか非WebLogicかにかかわらず、任意のアプリケーション・サーバーで実行されているWebサービスを呼び出すことができます。さらに、WebLogic Serverの一部として実行されるクライアントまたはWebLogic Serverライブラリにアクセスできない環境で実行されるスタンドアロン・クライアントも作成できます。
この項で説明したコマンド・ライン・ツールの他に、Oracle JDeveloperなどのIDEもプロキシ生成とテストに使用できます。詳細は、『Oracle Fusion Middleware Oracle WebLogic Server Webサービスの紹介』のOracle IDEを使用したWebサービスのビルドに関する項を参照してください。
|
注意: ユーザー定義のデータ型をパラメータまたは戻り値として実装するWebサービス操作を、動的クライアントを使用して呼び出すことはできません。動的クライアントでは、JAX-RPCのCallインタフェースを使用するためです。標準の(静的)クライアントでは、JAX-RPCのServiceインタフェースおよびStubインタフェースを使用するため、ユーザー定義のデータ型を実装するWebサービスを正常に呼び出すことができます。 |
Java API for XML based RPC (JAX-RPC)は、Webサービスの呼出しに使用するAPIを定義する仕様です。WebLogic ServerはJAX-RPC仕様を実装しています。
次の表で、JAX-RPCの中心的なインタフェースとクラスを簡単に説明します。
WebLogic ServerのWL_HOME/samples/server/examples/src/examples/webservicesディレクトリには、WebLogic Webサービスの作成と呼出しのサンプルがあります(WL_HOMEは、WebLogic Serverのメイン・ディレクトリです)。サンプルのビルドおよび実行方法の詳細は、ブラウザでWebページWL_HOME/samples/server/docs/index.htmlを開いて「WebLogic Server Examples」→「Examples」→「API」→「Web Services」ノードを展開してください。
|
注意: この項で説明するように、WebLogic Serverで実行されている(WebLogic Serverクラスパスにアクセスする)任意のJava SEまたはJava EEアプリケーションからWebサービスを呼び出すことができます。WebLogic Serverのライブラリにアクセスできない環境で実行されているスタンドアロンJavaアプリケーションのサポートについての詳細は、「Webサービス呼出し時のスタンドアロン・クライアントJARファイルの使用」を参照してください。 |
次の表は、Webサービスを呼び出すJava SEクライアントの作成の主な手順を示しています。
|
注意: 開発環境でのクライアント・アプリケーションのビルドやJavaファイルのコンパイルなどにAntを使用すること、およびWebサービスのクライアント・タスクで更新する必要のあるbuild.xmlファイルがすでに存在することを想定しています。開発環境でのAntの使用に関する一般情報は、「基本的なAnt build.xmlファイルの作成」を、この項で使用されるbuild.xmlファイルの完全な例は、「JavaクライアントのサンプルAntビルド・ファイル」を参照してください。 |
表6-2 Java SEクライアントからWebサービスを呼び出す手順
| # |
手順 | 説明 |
|---|---|---|
|
1 |
環境を設定します。 |
コマンド・ウィンドウを開いて、ドメイン・ディレクトリの |
|
2 |
|
|
|
3 |
Webサービスに関する情報(その操作のシグネチャ、ポートの名前など)を取得します。 |
「Webサービスに関する情報の取得」を参照してください。 |
|
4 |
Webサービス操作を呼び出すためのコードを含むクライアント・アプリケーションのJavaコードを記述します。 |
「Webサービスを呼び出すJavaクライアント・アプリケーション・コードの記述」を参照してください。 |
|
5 |
基本のAntビルド・ファイル |
「基本的なAnt build.xmlファイルの作成」を参照してください。 |
|
6 |
Javaクライアント・アプリケーションをコンパイルし、実行します。 |
「クライアント・アプリケーションのコンパイルと実行」を参照してください。 |
clientgen WebLogic WebサービスAntタスクは、クライアント・アプリケーションがWebLogic Webサービスと非WebLogic Webサービスの両方の呼出しに使用できるクライアント・アーティファクトを既存のWSDLファイルから生成します。アーティファクトは次を含みます:
呼出しの対象となる特定のWebサービスに対するJAX-RPC StubおよびServiceインタフェース実装のJavaクラス。
WSDLファイルで指定されたユーザー定義XMLスキーマ・データ型のJavaクラス。
Javaのユーザー定義のデータ型と、WSDLファイル内で指定されたそのデータ型に対応するXMLスキーマ型の間のマッピングに関する情報を格納するJAX-RPCマッピング・デプロイメント記述子ファイル。
WSDLファイルのクライアント側のコピー。
clientgen Antタスクの詳細(使用可能なすべての属性など)については、『Oracle Fusion Middleware WebLogic Oracle WebLogic Server Webサービス・リファレンス』の「Antタスク・リファレンス」を参照してください。
次の例のように、build.xmlファイルを更新してclientgen Antタスクに呼出しを追加します。
<taskdef name="clientgen"
classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
<target name="build-client">
<clientgen
wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
destDir="clientclasses"
packageName="examples.webservices.simple_client"
type="JAXRPC"/>
</target>
clientgen WebLogic WebサービスAntタスクを実行するには、このタスクの完全なJavaクラス名を標準のtaskdef Antタスクを使用して指定する必要があります。
クライアント側アーティファクトの作成に使用するWSDLファイルと、そうしたアーティファクトの生成先ディレクトリを指定するには、clientgen Antタスクのwsdl属性とdestDir属性を含める必要があります。packageName属性は省略できます。省略した場合、clientgenタスクではWSDLのtargetNamespaceに基づくパッケージ名が使用されます。typeも省略可能です。省略した場合のデフォルト値はJAXRPCです。
この例では、パッケージ名はクライアント・アプリケーションと同じパッケージ名examples.webservices.simple_clientに設定されます。パッケージ名をクライアント・アプリケーションとは異なる名前に設定した場合は、適切なクラス・ファイルをインポートする必要があります。たとえば、examples.webservices.complexというパッケージ名にした場合、クライアント・アプリケーションの以下のクラス・ファイルをインポートする必要があります。
import examples.webservices.complex.BasicStruct; import examples.webservices.complex.ComplexPortType; import examples.webservices.complex.ComplexService;
|
注意: clientgen AntタスクのdestFile属性を使用すると、生成されたJavaファイルを自動的にコンパイルして、すべてのアーティファクトをJARファイルにパッケージ化できます。コンパイルの詳細は、『Oracle Fusion Middleware Oracle WebLogic Server Webサービス・リファレンス』の「clientgen」を参照してください。 |
WSDLファイルで、Webサービス操作の入力パラメータまたは戻り値としてユーザー定義のデータ型が指定されている場合、clientgenはWSDLに定義されたXMLスキーマ・データ型のJava表現であるJavaBeanクラスを自動的に生成します。JavaBeanクラスは、destDirディレクトリに生成されます。
|
注意: ユーザー定義のJavaデータ型のパッケージは、WSDLのデータ型のXMLスキーマに基づくもので、JAX-RPCスタブのパッケージ名とは異なります。 |
この手順で説明されている追加のターゲット(cleanなど)を含む、完全なサンプルbuild.xmlファイルについては、「JavaクライアントのサンプルAntビルド・ファイル」を参照してください。
clientgen Antタスクを他のサポートAntタスクと一緒に実行するには、コマンド・ラインでbuild-clientターゲットを指定します。
prompt> ant build-client
clientclassesディレクトリで、clientgen Antタスクによって生成されたファイルやアーティファクトを確認します。
操作を呼び出すJavaクライアント・アプリケーション・コードの記述に先立って、Webサービスの名前と操作のシグネチャを知る必要があります。この情報を調べるには様々な方法があります。
この情報を得るのに最適なのは、clientgen Antタスクを使用してWebサービス固有のJAX-RPCスタブを生成し、生成された*.javaファイルを調べる方法です。これらのファイルは、destDir属性で指定したディレクトリ内のpackageName属性の値に対応したサブディレクトリ、またはWSDLのtargetNamespaceに基づくパッケージに対応したサブディレクトリ(packageName属性が指定されていない場合)に生成されます。
ServiceName.javaソース・ファイルには、Webサービスのポートを取得するためのgetPortName()メソッドが含まれています(ServiceNameはWebサービス名、PortNameはポート名です)。WebサービスがJWSファイルで実装されている場合、Webサービス名は@WebService JWSアノテーションのserviceName属性の値となり、ポート名は@WLHttpTransportアノテーションのportName属性の値となります。
PortType.javaファイルには、Webサービスのパブリック操作に対応するメソッド・シグネチャが含まれています(PortTypeはWebサービスのポートの種類です)。WebサービスがJWSファイルで実装されている場合、ポートの種類は@WebService JWSアノテーションのname属性の値となります。
Webサービスの実際のWSDLを調べることもできます。デプロイされているWebLogic WebサービスのWSDLの詳細は、「WebサービスのWSDLの参照」を参照してください。Webサービス名は、次のTraderService WSDLの抜粋に示すように、<service>要素内にあります。
<service name="TraderService">
<port name="TraderServicePort"
binding="tns:TraderServiceSoapBinding">
...
</port>
</service>
このWebサービス用に定義されている操作は、対応する<binding>要素の下に記述されています。たとえば次のWSDLの抜粋は、TraderService Webサービスにbuyとsellの2つの操作があることを示しています(わかりやすくするため、WSDLの関連部分のみを記載しています)。
<binding name="TraderServiceSoapBinding" ...>
...
<operation name="sell">
...
</operation>
<operation name="buy">
</operation>
</binding>
次のサンプル・コードでは、JavaアプリケーションがWebサービス操作を呼び出しています。このクライアント・アプリケーションは1つの引数(WebサービスのWSDL)を取ります。アプリケーションは次に標準JAX-RPC APIコードとclientgenによって生成されたServiceインタフェースのWebサービス固有の実装を使用して、Webサービスの操作を呼び出します。
この例では、ユーザー定義のデータ型(examples.webservices.complex.BasicStruct)を入力パラメータおよび戻り値として使用する操作を呼び出す方法も示します。clientgen Antタスクによって、このユーザー定義のデータ型のJavaコードが自動的に生成されます。
package examples.webservices.simple_client;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
// import the BasicStruct class, used as a param and return value of the
// echoComplexType operation. The class is generated automatically by
// the clientgen Ant task.
import examples.webservices.complex.BasicStruct;
/**
* This is a simple Java client application that invokes the
* the echoComplexType operation of the ComplexService Web service.
*/
public class Main {
public static void main(String[] args)
throws ServiceException, RemoteException {
ComplexService service = new ComplexService_Impl (args[0] + "?WSDL" );
ComplexPortType port = service.getComplexServicePort();
BasicStruct in = new BasicStruct();
in.setIntValue(999);
in.setStringValue("Hello Struct");
BasicStruct result = port.echoComplexType(in);
System.out.println("echoComplexType called. Result: " + result.getIntValue() + ", " + result.getStringValue());
}
}
上記の例で注目すべき点は以下のとおりです。
次のコードは、ComplexPortTypeスタブを作成する方法を示します。
ComplexService service = new ComplexService_Impl (args[0] + "?WSDL"); ComplexPortType port = service.getComplexServicePort();
ComplexService_Implスタブ・ファクトリはJAX-RPCのServiceインタフェースを実装します。ComplexService_Implのコンストラクタは、指定されているWSDL URI (args[0] + "?WSDL")に基づいてスタブを作成します。getComplexServicePort()メソッドは、ComplexPortTypeスタブ実装のインスタンスを返すために使用します。
次のコードは、ComplexService WebサービスのechoComplexType操作を呼び出す方法を示します。
BasicStruct result = port.echoComplexType(in);
echoComplexType操作は、BasicStructというユーザー定義データ型を返します。
アプリケーションからWebサービス操作を呼び出すメソッドは、生成されたJAX-RPCスタブからスローされるjava.rmi.RemoteExceptionおよびjavax.xml.rpc.ServiceExceptionをスローまたは捕捉する必要があります。
すべてのJavaファイル(クライアント・アプリケーションおよびclientgenによって生成されたファイルの両方)をクラス・ファイルにコンパイルするには、build.xmlファイルのbuild-clientターゲットにjavacタスクを追加します。該当箇所を次の例に太字で示します。
<target name="build-client">
<clientgen
wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
destDir="clientclasses"
packageName="examples.webservices.simple_client"
type="JAXRPC"/>
<javac
srcdir="clientclasses"
destdir="clientclasses"
includes="**/*.java"/>
<javac
srcdir="src"
destdir="clientclasses"
includes="examples/webservices/simple_client/*.java"/>
</target>
この例では、1番目のjavacタスクでclientgenによって生成されたclientclassesディレクトリ内のJavaファイルをコンパイルし、2番目のjavacタスクでカレント・ディレクトリのexamples/webservices/simple_clientサブディレクトリ(Javaクライアント・アプリケーションのソースの場所と想定されるディレクトリ)内にあるJavaファイルをコンパイルしています。
この例では、clientgenによって生成されたJavaソース・ファイルとコンパイル後のクラスが同じディレクトリ(clientclasses)に格納されます。プロトタイピングの段階ではこれで十分ですが、多くの場合はソース・コード(生成されたコードも含む)とコンパイルされたクラスを別々のディレクトリに格納するのがベスト・プラクティスです。これを行うには、両方のjavacタスクのdestdirに、srcdirディレクトリとは異なるディレクトリを設定します。また、clientgenによって生成された以下のファイルを、clientgenの出力先ディレクトリからjavacの出力先ディレクトリにコピーする必要もあります。その際、出力先のサブディレクトリの階層構造は同じになるようにします。
packageName/ServiceName_internaldd.xml packageName/ServiceName_java_wsdl_mapping.xml packageName/ServiceName_saved_wsdl.wsdl
packageNameは生成されたJAX-RPCスタブのパッケージに対応するサブディレクトリ階層構造、ServiceNameはWebサービスの名前です。
クライアント・アプリケーションを実行するには、次に示すように、javaタスクの呼出しを含むbuild.xmlにrunターゲットを追加します。
<path id="client.class.path">
<pathelement path="clientclasses"/>
<pathelement path="${java.class.path}"/>
</path>
<target name="run" >
<java
fork="true"
classname="examples.webServices.simple_client.Main"
failonerror="true" >
<classpath refid="client.class.path"/>
<arg line="http://${wls.hostname}:${wls.port}/complex/ComplexService" />
</target>
pathタスクは、CLASSPATHにclientclassesディレクトリを追加します。runターゲットはMainアプリケーションを呼び出し、デプロイされたWebサービスのURLを1つの引数として渡します。
この手順で説明されている追加のターゲット(cleanなど)を含む、完全なサンプルbuild.xmlファイルについては、「JavaクライアントのサンプルAntビルド・ファイル」を参照してください。
アーティファクトを再生成してクラスに再コンパイルするためにbuild-clientターゲットを再実行してから、runターゲットを実行してechoStruct操作を呼び出します。
prompt> ant build-client run
build.xmlファイルのbuild-clientおよびrunターゲットを使用して、開発プロセスの一環としてJavaクライアント・アプリケーションを繰返し更新、再ビルド、および実行できます。
次の例では、Javaクライアントを生成およびコンパイルするための完全なbuild.xmlファイルを示します。太字のセクションについては、「クライアントのアーティファクトを生成するためのclientgen Antタスクの使用」および「クライアント・アプリケーションのコンパイルと実行」を参照してください。
<project name="webservices-simple_client" default="all">
<!-- set global properties for this build -->
<property name="wls.hostname" value="localhost" />
<property name="wls.port" value="7001" />
<property name="example-output" value="output" />
<property name="clientclass-dir" value="${example-output}/clientclass" />
<path id="client.class.path">
<pathelement path="${clientclass-dir}"/>
<pathelement path="${java.class.path}"/>
</path>
<taskdef name="clientgen"
classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
<target name="clean" >
<delete dir="${clientclass-dir}"/>
</target>
<target name="all" depends="clean,build-client,run" />
<target name="build-client">
<clientgen
wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
destDir="${clientclass-dir}"
packageName="examples.webservices.simple_client"
type="JAXRPC"/>
<javac
srcdir="${clientclass-dir}" destdir="${clientclass-dir}"
includes="**/*.java"/>
<javac
srcdir="src" destdir="${clientclass-dir}"
includes="examples/webservices/simple_client/*.java"/>
</target>
<target name="run" >
<java fork="true"
classname="examples.webservices.simple_client.Main"
failonerror="true" >
<classpath refid="client.class.path"/>
<arg line="http://${wls.hostname}:${wls.port}/complex/ComplexService"
/>
</java>
</target>
</project>
WebLogic Webサービス内からのWebサービスの呼出しは、「Java SEクライアントからのWebサービスの呼出し」で説明している、他のJavaアプリケーションからの呼出しと似ています。ただし、呼び出されるWebサービスのJAX-RPCスタブを生成するclientgen Antタスクを使用するのではなく、呼出し側のWebサービスをコンパイルするjwsc Antタスク内で、<jws>要素の<clientgen>子要素を使用します。一方、他のWebサービスを呼び出すJWSファイルでは、ServiceおよびPortTypeインスタンスの取得に同じ標準JAX-RPC APIを使用して、Webサービス操作を呼び出します。
「Java SEクライアントからのWebサービスの呼出し」をすでに読み、理解していることが前提となります。また、クライアント・アプリケーションのビルドやJavaファイルのコンパイルなどに開発環境でAntを使用していること、そして別のWebサービスを呼び出すために更新したいWebサービスをビルドするbuild.xmlファイルをすでに持っていることも前提となります。
クライアントWebサービスをビルドするbuild.xmlファイルに加える必要のある変更は次のとおりです(このクライアントWebサービスが別のWebサービスを呼び出すことになります)。build.xmlファイルの完全なサンプルについては、「Webサービス・クライアントのサンプルbuild.xmlファイル」を参照してください。
JWSファイル(別のWebサービスを呼び出すWebサービスを実装しているもの)を指定する<jws>要素に、<clientgen>子要素を追加します。呼び出すWebサービスのWSDLに、必要なwsdl属性を設定します。JAX-RPCクライアント・スタブの生成先とするパッケージに、必要なpackageName属性を設定します。
クライアントWebサービスを実装するJWSファイルに加える必要のある変更は次のとおりです。JWSファイルの完全なサンプルについては、「Webサービスを呼び出すサンプルJWSファイル」を参照してください。
jwsc Antタスクの<clientgen>子要素で生成される一連のファイルをインポートします。これらには、呼び出されるWebサービスの操作でパラメータまたは戻り値として使用するユーザー定義データ型のJava表現だけでなく、呼び出されるWebサービスのJAX-RPCスタブも含まれます。
|
注意: ユーザー定義のデータ型は、clientgenで指定されるパッケージ内ではなく、WSDLのXMLスキーマ・データ型に基づくパッケージ内に生成されます。ただし、JAX-RPCスタブでは<clientgen>要素のpackageName属性で指定されるパッケージ名が使用されます。 |
Webサービスの呼出しを含むメソッドを、java.rmi.RemoteExceptionとjavax.xml.rpc.ServiceExceptionの両方をスローまたは捕捉するように更新します。
JAX-RPCのServiceおよびPortTypeスタブ実装を取得して、通常どおりポート上で操作を呼び出します。詳細は、「Webサービスを呼び出すJavaクライアント・アプリケーション・コードの記述」を参照してください。
次のサンプルbuild.xmlファイルでは、別のWebサービスを呼び出すWebサービスを作成する方法を示します。別のWebサービスを呼び出さない単純なWebサービスをビルドするためのbuild.xmlと異なっている部分は、太字で示されています。
この場合のbuild-serviceターゲットは、単純なWebサービスをビルドするターゲットとよく似ています。唯一の違いは、呼び出すWebサービスをビルドするjwsc Antタスクに<jws>要素の<clientgen>子要素も含まれるという点で、これによってjwscでは必要なJAX-RPCクライアント・スタブも生成されるようになります。
<project name="webservices-service_to_service" default="all">
<!-- set global properties for this build -->
<property name="wls.username" value="weblogic" />
<property name="wls.password" value="weblogic" />
<property name="wls.hostname" value="localhost" />
<property name="wls.port" value="7001" />
<property name="wls.server.name" value="myserver" />
<property name="ear.deployed.name" value="ClientServiceEar" />
<property name="example-output" value="output" />
<property name="ear-dir" value="${example-output}/ClientServiceEar" />
<property name="clientclass-dir" value="${example-output}/clientclasses" />
<path id="client.class.path">
<pathelement path="${clientclass-dir}"/>
<pathelement path="${java.class.path}"/>
</path>
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<taskdef name="clientgen"
classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
<taskdef name="wldeploy"
classname="weblogic.ant.taskdefs.management.WLDeploy"/>
<target name="all" depends="clean,build-service,deploy,client" />
<target name="clean" depends="undeploy">
<delete dir="${example-output}"/>
</target>
<target name="build-service">
<jwsc
srcdir="src"
destdir="${ear-dir}" >
<jws
file="examples/webservices/service_to_service/ClientServiceImpl.java"
type="JAXRPC">
<clientgen
wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
packageName="examples.webservices.complex" />
</jws>
</jwsc>
</target>
<target name="deploy">
<wldeploy action="deploy" name="${ear.deployed.name}"
source="${ear-dir}" user="${wls.username}"
password="${wls.password}" verbose="true"
adminurl="t3://${wls.hostname}:${wls.port}"
targets="${wls.server.name}" />
</target>
<target name="undeploy">
<wldeploy action="undeploy" name="${ear.deployed.name}"
failonerror="false"
user="${wls.username}"
password="${wls.password}" verbose="true"
adminurl="t3://${wls.hostname}:${wls.port}"
targets="${wls.server.name}" />
</target>
<target name="client">
<clientgen
wsdl="http://${wls.hostname}:${wls.port}/ClientService/ClientService?WSDL"
destDir="${clientclass-dir}"
packageName="examples.webservices.service_to_service.client"
type="JAXRPC"/>
<javac
srcdir="${clientclass-dir}" destdir="${clientclass-dir}"
includes="**/*.java"/>
<javac
srcdir="src" destdir="${clientclass-dir}"
includes="examples/webservices/service_to_service/client/**/*.java"/>
</target>
<target name="run">
<java classname="examples.webservices.service_to_service.client.Main"
fork="true"
failonerror="true" >
<classpath refid="client.class.path"/>
<arg
line="http://${wls.hostname}:${wls.port}/ClientService/ClientService"/>
</java>
</target>
</project>
次に示すサンプルJWSファイル(ClientServiceImpl.java)は、ClientServiceというWebサービスを実装しており、このWebサービスに含まれている操作がComplexServiceというWebサービスのechoComplexType操作を呼び出します。この操作では、パラメータとしても戻り値としてもユーザー定義データ型(BasicStruct)を使用します。該当するコードを太字で示し、例の後で説明を加えます。
package examples.webservices.service_to_service;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import javax.jws.WebService;
import javax.jws.WebMethod;
import weblogic.jws.WLHttpTransport;
// Import the BasicStruct data type, generated by clientgen and used
// by the ComplexService Web Service
import examples.webservices.complex.BasicStruct;
// Import the JAX-RPC Stubs for invoking the ComplexService Web Service.
// Stubs generated by clientgen
import examples.webservices.service_to_service.ComplexPortType;
import examples.webservices.service_to_service.ComplexService_Impl;
import examples.webservices.service_to_service.ComplexService;
@WebService(name="ClientPortType", serviceName="ClientService",
targetNamespace="http://examples.org")
@WLHttpTransport(contextPath="ClientService", serviceUri="ClientService",
portName="ClientServicePort")
public class ClientServiceImpl {
@WebMethod()
public String callComplexService(BasicStruct input, String serviceUrl)
throws ServiceException, RemoteException
{
// Create service and port stubs to invoke ComplexService
ComplexService service = new ComplexService_Impl(serviceUrl + "?WSDL");
ComplexPortType port = service.getComplexServicePort();
// Create service and port stubs to invoke ComplexService
ComplexService service = new ComplexService_Impl(serviceUrl + "?WSDL");
ComplexPortType port = service.getComplexServicePortTypePort();
// Invoke the echoComplexType operation of ComplexService
BasicStruct result = port.echoComplexType(input);
System.out.println("Invoked ComplexPortType.echoComplexType." );
return "Invoke went okay! Here's the result: '" + result.getIntValue() + ", " + result.getStringValue() + "'";
}
}
別のWebサービスを呼び出すJWSファイルをプログラミングする際は、次のガイドラインに従います。ガイドラインのコード・スニペットは、前の例では太字で示されています。
呼び出されるWebサービスで使用されるユーザー定義データ型をインポートします。この例では、ComplexServiceでBasicStruct JavaBeanを使用しています。
import examples.webservices.complex.BasicStruct;
ComplexService WebサービスのJAX-RPCスタブをインポートします。このスタブは、<jws>の<cliengen>子要素によって生成されます。
import examples.webservices.service_to_service.ComplexPortType; import examples.webservices.service_to_service.ComplexService_Impl; import examples.webservices.service_to_service.ComplexService;
クライアントWebサービスがServiceExceptionおよびRemoteExceptionをスローまたは捕捉するようにします。
throws ServiceException, RemoteException
ComplexServiceのJAX-RPC ServiceおよびPortTypeインスタンスを作成します。
ComplexService service = new
ComplexService_Impl(serviceUrl + "?WSDL");
ComplexPortType port = service.getComplexServicePortTypePort();
ComplexServiceのechoComplexType操作を、直前にインスタンス化したポートを使用して呼び出します。
BasicStruct result = port.echoComplexType(input);
このドキュメントでは、clientgenまたはwsdlc Antタスクによって生成されたクライアント側アーティファクトを使用してWebサービスを呼び出す場合に、WebLogic Serverクラス全体がCLASSPATHに指定されていることを前提としています。ただし、ご使用のコンピュータにWebLogic Serverがインストールされていない場合でも、この項で説明するようにスタンドアロンのWebLogic Webサービス・クライアントJARファイルを使用することで、Webサービスを呼び出すことができます。
スタンドアロン・クライアントJARファイルは、次のような基本的なクライアント側の機能をサポートしています。
clientgen Antタスクの双方によって作成されるクライアント側アーティファクトでの使用
SOAPメッセージの処理
クライアント側のSOAPメッセージ・ハンドラの使用
MTOMの使用
JAX-RPC Webサービスの呼出し
SSLの使用
ただし、スタンドアロン・クライアントJARファイルは、次の高度な機能を使用するWebサービスの呼出しはサポートしていません。
Webサービスの信頼性のあるSOAPメッセージング
メッセージ・レベルのセキュリティ(WS-Security)
会話
非同期のリクエスト/レスポンス
バッファリング
JMSトランスポート
スタンドアロンのWebLogic Webサービス・クライアントJARファイルをクライアント・アプリケーションで使用するには、次の手順に従います。
ファイルWL_HOME/server/lib/wseeclient.zipを、WebLogic Serverをホストしているコンピュータからクライアント・コンピュータにコピーします。WL_HOMEは、WebLogic Serverのインストール・ディレクトリ(/Oracle/Middleware/wlserver_10.3など)を表します。
wseeclient.zipファイルを、適切なディレクトリに解凍します。たとえば、クライアント・アプリケーションで使用している他のクラスが格納されているディレクトリを解凍先にします。
wseeclient.jarファイル(wseeclient.zipファイルから解凍)を、CLASSPATHに追加します。
|
注意: また、Antクラスが含まれるJARファイル(ant.jar)が、確実にCLASSPATHに格納されるようにしてください。このJARファイルは通常、Antディストリビューションのlibディレクトリ内にあります。 |
プロキシ・サーバーを使用すると、クライアント・アプリケーションから、呼び出されるWebサービスをホストするアプリケーション・サーバー(WebLogic、非WebLogicいずれでも)へのリクエストをプロキシできます。通常、プロキシ・サーバーは、アプリケーション・サーバーがファイアウォールの内側にある場合に使用します。クライアント・アプリケーションでプロキシ・サーバーを指定するには、WebLogic HttpTransportInfo APIでプログラム的に行う方法と、システム・プロパティを使用する方法の2つがあります。
標準のjava.net.*クラスとWebLogic固有のHttpTransportInfo APIを使用することにより、Webサービスの呼出しをプロキシするプロキシ・サーバーの詳細を、Javaクライアント・アプリケーション自体の中でプログラム的に指定できます。java.netクラスを使用して、プロキシ・サーバーを示すProxyオブジェクトを作成し、次にWebLogic APIとプロパティを使用してJAX-RPCスタブ上でプロキシ・サーバーを設定します(HttpProxySampleService Webサービスのecho操作を呼び出す次のサンプル・クライアントを参照)。太字で示したコードについては、例の後で説明します。
package dev2dev.proxy.client; import java.net.Proxy; import java.net.InetSocketAddress; import weblogic.wsee.connection.transport.http.HttpTransportInfo; /** * Sample client to invoke a service through a proxy server via * programmatic API */ public class HttpProxySampleClient { public static void main(String[] args) throws Throwable{ assert args.length == 5; String endpoint = args[0]; String proxyHost = args[1]; String proxyPort = args[2]; String user = args[3]; String pass = args[4]; //create service and port HttpProxySampleService service = new HttpProxySampleService_Impl(); HttpProxySamplePortType port = service.getHttpProxySamplePortTypeSoapPort(); //set endpoint address ((Stub)port)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, endpoint); //set proxy server info Proxy p = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, Integer.parseInt(proxyPort))); HttpTransportInfo info = new HttpTransportInfo(); info.setProxy(p); ((Stub)port)._setProperty("weblogic.wsee.connection.transportinfo",info); //set proxy-authentication info ((Stub)port)._setProperty("weblogic.webservice.client.proxyusername",user); ((Stub)port)._setProperty("weblogic.webservice.client.proxypassword",pass); //invoke String s = port.echo("Hello World!"); System.out.println("echo: " + s); } }
上記の例のうち、留意すべきセクションは、次のとおりです。
必要なjava.net.*クラスのインポート。
import java.net.Proxy; import java.net.InetSocketAddress;
WebLogic HttpTransportInfo APIのインポート。
import weblogic.wsee.connection.transport.http.HttpTransportInfo;
プロキシ・サーバーを表すProxyオブジェクトの作成。
Proxy p = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, Integer.parseInt(proxyPort)));
引数proxyHostおよびproxyPortは、プロキシ・サーバーのホスト・コンピュータおよびポートを表します。
HttpTransportInfoオブジェクトを作成し、setProxy()メソッドを使用してプロキシ・サーバー情報を設定します。
HttpTransportInfo info = new HttpTransportInfo(); info.setProxy(p);
weblogic.wsee.connection.transportinfo WebLogicスタブ・プロパティを使用して、JAX-RPCスタブ上でHttpTransportInfoオブジェクトを設定します。
((Stub)port)._setProperty("weblogic.wsee.connection.transportinfo",info);
WebLogic固有のスタブ・プロパティweblogic.webservice.client.proxyusernameおよびweblogic.webservice.client.proxypasswordを使用して、プロキシ・サーバーへのアクセスが認証されているユーザーのユーザー名とパスワードを指定します。
((Stub)port)._setProperty("weblogic.webservice.client.proxyusername",user);
((Stub)port)._setProperty("weblogic.webservice.client.proxypassword",pass);
別の方法としては、次の例に示すように、HttpTransportInfo APIのsetProxyUsername()およびsetProxyPassword()メソッドを使用してプロキシ・ユーザー名とパスワードを設定することもできます。
info.setProxyUsername("juliet".getBytes());
info.setProxyPassword("secret".getBytes());
プロキシ・サーバーの指定にシステム・プロパティを使用するには、クライアント・アプリケーションの記述は標準的な方式で行い、クライアント・アプリケーションの実行時にシステム・プロパティを指定します。
Javaの標準的なシステム・プロパティを使用するか、またはWebLogicの履歴プロパティを使用できます。proxySet systemプロパティがfalseに設定される場合(proxySet=false)、プロキシ・プロパティが無視され、プロキシは使用されません。
次の表に、Javaシステム・プロパティの概要を示します。この場合、proxySetシステム・プロパティを設定しないでください。
表6-3 プロキシ・サーバーの指定に使用するJavaシステム・プロパティ
| プロパティ | 説明 |
|---|---|
|
http.proxyHost=proxyHost または https.proxyHost=proxyHost |
プロキシ・サーバーが動作しているホスト・コンピュータの名前。HTTP over SSLに対してhttps.proxyHostを使用します。 |
|
http.proxyPort=proxyPort または https.proxy.Port=proxyPort |
プロキシ・サーバーがリスニングしているポート。HTTP over SSLに対してhttps.proxyPortを使用します。 |
|
http.nonProxyHosts= hostname|hostname|... |
プロキシをバイパスし、直接アクセスするホストのリスト。各ホスト名を「|」文字で区切ります。このプロパティはHTTPおよびHTTPSの両方に適用されます。 |
以下のAntビルド・スクリプトの抜粋では、clients.InvokeMyServiceというクライアント・アプリケーションを呼び出す場合のJavaシステム・プロパティの設定例を示します。
<target name="run-client">
<java fork="true"
classname="clients.InvokeMyService"
failonerror="true">
<classpath refid="client.class.path"/>
<arg line="${http-endpoint}"/>
<jvmarg line=
"-Dhttp.proxyHost=${proxy-host}
-Dhttp.proxyPort=${proxy-port}
-Dhttp.nonProxyHosts=${mydomain}"
/>
</java>
</target>
次の表に、WebLogicシステム・プロパティの概要を示します。この場合、proxySetシステム・プロパティをtrueに設定する必要があります。
表6-4 プロキシ・サーバーの指定に使用するWebLogicシステム・プロパティ
| プロパティ | 説明 |
|---|---|
|
proxySet=true |
歴史的なWebLogicプロキシ・プロパティを使用することを指定するフラグ。 |
|
proxyHost=proxyHost |
プロキシ・サーバーが動作しているホスト・コンピュータの名前。 |
|
proxyPort=proxyPort |
プロキシ・サーバーがリスニングしているポート。 |
|
weblogic.webservice.client.proxyusername=username |
プロキシ・サーバーにアクセスするために使用するユーザー名。 |
|
weblogic.webservice.client.proxypassword=password |
プロキシ・サーバーにアクセスするために使用するパスワード。 |
以下のAntビルド・スクリプトの抜粋では、clients.InvokeMyServiceというクライアント・アプリケーションを呼び出す場合のWebLogicシステム・プロパティの設定例を示します。
<target name="run-client">
<java fork="true"
classname="clients.InvokeMyService"
failonerror="true">
<classpath refid="client.class.path"/>
<arg line="${http-endpoint}"/>
<jvmarg line=
"-DproxySet=true
-DproxyHost=${proxy-host}
-DproxyPort=${proxy-port}
-Dweblogic.webservice.client.proxyusername=${proxy-username}
-Dweblogic.webservice.client.proxypassword=${proxy-passwd}"
/>
</java>
</target>
WebLogic Serverでは本番再デプロイメントをサポートしているため、更新後の新しいバージョンのWebLogic Webサービスを同じWebサービスの古いバージョンと並行してデプロイできます。
WebLogic Serverでは、新しいクライアントのリクエストのみが新しいバージョンに転送されるように、クライアント接続が自動的に管理されます。再デプロイメント時にすでにWebサービスに接続していたクライアントは、作業が完了するまで古いバージョンのサービスを使用し続け、それらの作業が完了した時点で、WebLogic Serverが古いWebサービスを自動的にリタイアします。クライアントが会話形式のWebサービスまたは信頼性のあるWebサービスに接続している場合、既存の会話シーケンスまたは信頼性のあるメッセージングのシーケンスがクライアントによって明示的に終了されるか、タイムアウトになったときに、クライアントの作業が完了したと見なされます。
Webサービスの新しいバージョンで次のWebサービス・アーティファクトが変更されていなければ、その新しいバージョンで古いクライアント・アプリケーションを引き続き使用できます。
Webサービスを記述するWSDL
Webサービスに添付されたWS-Policyファイル
上記のアーティファクトのいずれかが変更されている場合、clientgen Antタスクを再び実行して、クライアント・アプリケーションで使用されるJAX-RPCスタブを再生成する必要があります。
たとえば、Webサービスの新しいバージョンで操作のシグネチャを変更すると、Webサービスの新しいバージョンを記述するWSDLファイルも変更されます。この場合、JAX-RPCスタブを再生成する必要があります。ただし、単に操作の実装のみを変更し、操作のパブリック・コントラクトは変更しない場合、既存のクライアント・アプリケーションを引き続き使用できます。
WebLogic Serverには、WebLogic Webサービスの呼出しに使用するJAX-RPCスタブに対して設定できる一連のスタブ・プロパティが用意されています。プロパティの設定には、次の例のようにStub._setProperty()メソッドを使用します。
((Stub)port)._setProperty(WLStub.MARSHAL_FORCE_INCLUDE_XSI_TYPE,"true");
ほとんどのスタブ・プロパティはWLStubクラスに定義されています。詳細は、Oracle Fusion Middleware Oracle WebLogic Server APIリファレンス』の「weblogic.wsee.jaxrpc.WLStub」を参照してください。
WLStubクラスに定義されていない付加的なスタブ・プロパティについては、以下の表で説明します。
表6-5 付加的なスタブ・プロパティ
| スタブ・プロパティ | 説明 |
|---|---|
|
Webサービスの呼出しを試行しているクライアント・アプリケーションが接続を待機する時間(ミリ秒単位)を指定します。指定した時間が経過しても接続が確立していない場合、その試行はタイムアウトになります。 |
|
クライアント・アプリケーションが呼び出しているWebサービスからのレスポンスを待機する時間(ミリ秒単位)を指定します。指定した時間が経過してもレスポンスが到着していない場合、そのクライアントはタイムアウトになります。 |
|
クライアント・アプリケーションがWebLogic Serverからの署名されたレスポンスの検証に使用する証明書を指定します。デフォルトでは、検証に使用される証明書がSOAPレスポンス・メッセージ自体に格納されます。これが不可能な場合に、このスタブ・プロパティを使用して、別の証明書を指定します。 このスタブ・プロパティは、WebLogic Serverコンテナの内部で実行されるクライアント・アプリケーションのみに適用され、スタンドアロンのクライアント・アプリケーションには適用されません。 このプロパティの値は、 |
|
クライアント・アプリケーションが、WebLogic Serverに送信されるSOAPリクエスト・メッセージの暗号化に使用する証明書を指定します。デフォルトでは、クライアント・アプリケーションはWebサービスのWSDLでパブリッシュされているパブリック証明書を使用します。これが不可能な場合に、このスタブ・プロパティを使用して、別の証明書を指定します。 このスタブ・プロパティは、WebLogic Serverコンテナの内部で実行されるクライアント・アプリケーションのみに適用され、スタンドアロンのクライアント・アプリケーションには適用されません。 このプロパティの値は、 |
|
Webサービス操作呼出しのSOAPメッセージに、各パラメータのXMLスキーマ・データ型を含める必要があることを指定します。デフォルトでは、各パラメータのデータ型はSOAPメッセージには含まれません。 次に例を示すように、このプロパティを <soapenv:Envelope> ... <maxResults xsi:type="xs:int">10</maxResults> ... デフォルトでは(または、このプロパティを <soapenv:Envelope> ... <maxResults>10</maxResults> ... このプロパティの有効な値は、 |
レスポンス(発信) SOAPメッセージの文字エンコーディングを設定するには、weblogic.wsee.jaxrpc.WLStub.CHARACTER_SET_ENCODING WLStubプロパティを使用します。設定できる値は次の2つです。
UTF-8
UTF-16
クライアント・アプリケーションからの以下の抜粋コードでは、文字エンコーディングをUTF-16に設定する方法を示します。
Simple port = service.getSimpleSoapPort(); ((Stub) port)._setProperty(weblogic.wsee.jaxrpc.WLStub.CHARACTER_SET_ENCODING, "UTF-16"); port.invokeMethod();
詳細は、Oracle Fusion Middleware Oracle WebLogic Server APIリファレンス』の「weblogic.wsee.jaxrpc.WLStub」を参照してください。