Oracle® Fusion Middleware Oracle WebLogic Server JAX-RPC Webサービスの開発 12c (12.1.1) E48037-01 |
|
前 |
次 |
この章では、Java API for XML-based RPC (JAX-RPC)を使用してWebLogic Webサービス・クライアントを開発する方法について説明します。
この章では、以下のトピックについて説明します。
注意: 次のセクションでは、メッセージ保護されたWebサービスの呼出しについては説明していないため、メッセージ保護されたWebサービスの呼出しについては、『Oracle WebLogic Server WebLogic Webサービスの保護』の「クライアント・アプリケーションの更新によるメッセージ保護されたWebサービスの呼出し」を参照してください。 |
Webサービスの起動とは、Webサービスを使用するためにクライアント・アプリケーションが実行する操作のことです。Webサービスを呼び出すクライアント・アプリケーションは、Java、Microsoft .NETなどの任意のテクノロジを使用して記述できます。
クライアント・アプリケーションには以下の2種類があります。
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 WebLogic Server WebLogic 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のEXAMPLES_HOME
/wl_server/examples/src/examples/webservices
ディレクトリにはオプションで、WebLogic Webサービスの作成と呼出しのサンプルがあります(EXAMPLES_HOME
は、WebLogic Serverのサンプル・コードが構成されているディレクトリです)。デフォルトのパスはORACLE_HOME
\user_projects\applications
です。サンプルのビルドおよび実行方法の詳細は、ブラウザでWebページEXAMPLES_HOME
\wl_server/docs/index.html
を開いて「WebLogic Server Examples」-「Examples」-「API」-「Web Services」ノードを展開してください。詳細は、『Oracle WebLogic Serverの理解』のサンプル・アプリケーションおよびサンプル・コードに関する項を参照してください。
注意: この項で説明するように、WebLogic Serverで実行されている(WebLogic Serverクラスパスにアクセスする)任意のJava SEまたはJava EEアプリケーションからWebサービスを呼び出すことができます。WebLogic Serverのライブラリにアクセスできない環境で実行されているスタンドアロンJavaアプリケーションのサポートの詳細は、「Webサービス呼出し時のスタンドアロン・クライアントJARファイルの使用」を参照してください。 |
次の表は、Webサービスを呼び出すJava SEクライアントの作成の主な手順を示しています。
注意: 開発環境でのクライアント・アプリケーションのビルドやJavaファイルのコンパイルなどにAntを使用すること、およびWebサービスのクライアント・タスクで更新する必要のある |
表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 WebLogic Server WebLogic 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;
注意:
|
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
属性の値に対応したサブディレクトリに生成されます。packageName属性が指定されていない場合、WSDLのtargetNamespace
に基づくパッケージに対応したサブディレクトリに生成されます。
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スタブも含まれます。
注意: ユーザー定義のデータ型は、 |
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ファイルをクライアント・アプリケーションで使用するには、次の手順に従います。
ファイルORACLE_HOME
/wlserver/modules/clients/com.oracle.webservices.wls.jaxrpc-client_12.1.2.jar
を、WebLogic Serverをホストするコンピュータからクライアントコンピュータにコピーします(ORACLE_HOME
はOracle WebLogic Serverのインストール時にOracleホームとして指定したディレクトリ、domainNameはドメインの名前です)。
JARファイルをCLASSPATHに追加します。
注意: JARファイルでクラスのサブセットが必要になるため、Antクラスを含むJARファイル( |
プロキシ・サーバーを使用すると、クライアント・アプリケーションから、呼び出される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 WebLogic Server Java 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 WebLogic Server Java APIリファレンスのweblogic.wsee.jaxrpc.WLStub
に関する項を参照してください。