ナビゲーションをスキップ

WebLogic Web サービス プログラマーズ ガイド

  前 次 前/次ボタンと目次ボタンとの区切り線 目次  

Web サービスの呼び出し

以下の節では、Web サービスの呼び出しについて説明します。

 


Web サービスの呼び出しの概要

Web サービスの呼び出しは、クライアント アプリケーションが Web サービスを使用するために実行するアクションです。Web サービスを呼び出すクライアント アプリケーションは、Java、Microsoft .NET などの任意のテクノロジを使用して記述できます。

注意 : この章では、クライアント アプリケーションという用語を、WebLogic クライアント クラスを使用して WebLogic Server および非 WebLogic Server の Web サービスを呼び出すスタンドアロン クライアントと、WebLogic Server にデプロイされている J2EE コンポーネント (EJB など) の内部で動作するクライアントの両方の意味で使用しています。

以降の節では、JAX-RPC 仕様 (バージョン 1.1) の BEA の実装を使用して Java クライアント アプリケーションから Web サービスを呼び出す方法について説明します。この実装を使用することで、WebLogic および非 WebLogic にかかわらず任意のアプリケーション サーバで実行されている Web サービスを呼び出すことができます。さらには、スタンドアロン クライアント アプリケーションまたは WebLogic Server の一部として実行されるクライアント アプリケーションのどちらも作成できます。

警告 : ユーザ定義のデータ型をパラメータまたは戻り値として使用する Web サービス オペレーションを、動的クライアントを使用して呼び出すことはできません。動的クライアントでは、JAX-RPC の Call インタフェースを使用するためです。標準の (静的) クライアントでは、JAX-RPC の Service インタフェースおよび Stub インタフェースを使用するため、ユーザ定義のデータ型を使用する Web サービスを正常に呼び出すことができます。

クライアント アプリケーションの種類

この節では、以下の 2 種類のクライアント アプリケーションについて説明します。

JAX-RPC

Java API for XML based RPC (JAX-RPC) は、Web サービスの呼び出しに使用する API を定義する Sun Microsystems の仕様です。

次の表で、JAX-RPC の中心的なインタフェースとクラスを簡単に説明します。

表 8-1 JAX-RPC のインタフェースとクラス

javax.xml.rpc のインタフェースまたはクラス

説明

Service

主要なクライアント インタフェース。

ServiceFactory

Service インスタンスの生成に使用するファクトリ クラス。

Stub

Web サービスのオペレーションを呼び出すためのクライアント プロキシの基本クラス。

Call

Web サービスを動的に呼び出すのに使用する。

JAXRPCException

Web サービスの呼び出し中にエラーが発生した場合に送出される例外。

WebLogic Server には、JAX-RPC 1.1 仕様の実装が組み込まれています。

JAX-RPC の詳細については、http://java.sun.com/xml/jaxrpc/index.html を参照してください。

JAX-RPC を使用して Web サービスを呼び出す方法に関するチュートリアルについては、http://java.sun.com/webservices/docs/ea1/tutorial/doc/JAXRPC.html を参照してください。

clientgen Ant タスク

clientgen WebLogic Web サービス Ant タスクは、クライアント アプリケーションが WebLogic Web サービスと非 WebLogic Web サービスの両方の呼び出しに使用できるクライアント アーティファクトを既存の WSDL ファイルから生成します。以下のようなアーティファクトがあります。

clientgen Ant タスクの詳細 (使用できるすべての属性など) については、「Ant タスク リファレンス」を参照してください。

Web サービスを呼び出すクライアントの例

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] ノードをクリックしてください。

 


スタンドアロン クライアントからの Web サービスの呼び出し : 主な手順

以下の手順では、開発環境でのクライアント アプリケーションのビルドや Java ファイルのコンパイルなどに Ant を使用していることを前提としています。また、Web サービスのクライアント タスクで更新する必要のある build.xml ファイルがすでに存在していることを想定しています。

開発環境での Ant の使用については、「基本的な Ant build.xml ファイルの作成」を参照してください。この節で使用する build.xml ファイルのサンプル全体が必要な場合は、「スタンドアロン Java クライアントのサンプル Ant ビルド ファイル」を参照してください。

Web サービスを呼び出す Java スタンドアロン クライアント アプリケーションを作成するには、次の手順に従います。

  1. コマンド シェルを開き、環境を設定します。
  2. Windows NT では、ドメイン ディレクトリにある setDomainEnv.cmd コマンドを実行します。WebLogic Server ドメインのデフォルトの位置は、BEA_HOME\user_projects\domains\domainName です。BEA_HOME は BEA Products の最上位のインストール ディレクトリで、domainName はドメインの名前です。

    UNIX では、ドメイン ディレクトリにある setDomainEnv.sh コマンドを実行します。WebLogic Server ドメインのデフォルトの場所は、BEA_HOME/user_projects/domains/domainName です。BEA_HOME は BEA Products の最上位のインストール ディレクトリ、domainName はドメインの名前です。

  3. build.xml ファイルを更新して、Web サービスの呼び出しに必要なクライアントサイド アーティファクトを生成する clientgen Ant タスクが実行されるようにします。
  4. クライアントのアーティファクトを生成するための clientgen Ant タスクの使用」を参照してください。

  5. Web サービスに関する情報 (そのオペレーションのシグネチャ、ポートの名前など) を取得します。
  6. Web サービスに関する情報の取得」を参照してください。

  7. Web サービス オペレーションの呼び出しを含むクライアント アプリケーションの Java コードを記述します。
  8. Java クライアント アプリケーション コードの記述」を参照してください。

  9. Java クライアント アプリケーションをコンパイルし、実行します。
  10. クライアント アプリケーションのコンパイルと実行」を参照してください。

クライアントのアーティファクトを生成するための clientgen 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"/>
</target>

clientgen WebLogic Web サービス Ant タスクを実行するためには、その前に標準の taskdef Ant タスクを使用して、タスクの完全な Java クラス名を指定する必要があります。

クライアントサイド アーティファクトの作成に使用する WSDL ファイル、およびそれらのアーティファクトの生成先となるディレクトリを指定するには、clientgen Ant タスクの wsdl 属性と destDir 属性を含める必要があります。packageName 属性は省略できます。省略した場合は、WSDL の targetNamespace に基づくパッケージ名が使用されます。

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 タスクによって生成されたファイルとアーティファクトを確認します。

Web サービスに関する情報の取得

オペレーションを呼び出す Java クライアント アプリケーション コードの記述に先立って、Web サービスの名前とオペレーションのシグネチャを知る必要があります。Web サービスに関する情報を調べるにはさまざまな方法があります。

一番良いのは、clientgen Ant タスクを使用して Web サービス固有の JAX-RPC スタブを生成し、生成された *.java ファイルを調べる方法です。これらのファイルは、destDir 属性で指定したディレクトリ内の、packageName 属性の値に対応するサブディレクトリに生成されます。packageName 属性が指定されていない場合は、WSDL のtargetNamespace に基づくパッケージに対応するサブディレクトリに生成されます。

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 サービスには、buysell の 2 つのオペレーションがあることを示しています (わかりやすくするため、WSDL の関連部分のみを記載しています)。

  <binding name="TraderServiceSoapBinding" ...>
...
<operation name="sell">
...
</operation>
<operation name="buy">
</operation>
</binding>

Java クライアント アプリケーション コードの記述

次のコードは、スタンドアロン アプリケーションから Web サービス オペレーションを呼び出すサンプルです。

このクライアント アプリケーションは、1 つの引数 (Web サービスの WSDL) を取ります。アプリケーションは標準 JAX-RPC API コードを使用して、clientgen によって生成された Service インタフェースの WebLogic Server 固有の実装を使用して Web サービスのオペレーションを呼び出します。

このサンプルでは、ユーザ定義のデータ型 (examples.webservices.complex.BasicStruct) を入力パラメータおよび戻り値として使用するオペレーションを呼び出す方法も示します。clientgen Ant タスクでは、このユーザ定義のデータ型の Java コードが自動的に生成されます。

package examples.webservices.simple_client;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
// echoComplexType オペレーションのパラメータおよび戻り値として使用される
// BasicStruct クラスをインポートする。
// このクラスは clientgen Ant タスクによって自動的に生成される
import examples.webservices.complex.BasicStruct;
/**
* ComplexService Web サービスの echoComplexType オペレーションを呼び出す
 * 簡単なスタンドアロンのクライアント アプリケーション
 *
 * @author Copyright (c) 2005 by BEA Systems.All Rights Reserved.
 */
public class Main {
  public static void main(String[] args)
throws ServiceException, RemoteException{
    ComplexService service = new ComplexService_Impl (args[0]);
   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());
}
}

上記の例で注目すべき点は以下のとおりです。

アプリケーションから Web サービス オペレーションを呼び出すメソッドは、java.rmi.RemoteException および javax.xml.rpc.ServiceException を送出または捕捉する必要があります。これらの例外は、生成された JAX-RPC スタブから送出されます。

クライアント アプリケーションのコンパイルと実行

すべての 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"/>
    <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.xmlrun ターゲットを追加します。次に例を示します。

<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?WSDL" />
</java>
</target>

path タスクは、CLASSPATH に clientclasses ディレクトリを追加します。run ターゲットは Main アプリケーションを呼び出し、デプロイされた Web サービスの WSDL を 1 つの引数として渡します。

この手順で説明される追加のターゲット (clean など) が含まれている、完全なサンプル build.xml ファイルについては、「スタンドアロン Java クライアントのサンプル Ant ビルド ファイル」を参照してください。

アーティファクトを再生成してクラスにコンパイルするため build-client ターゲットを再実行してから、run ターゲットを実行して echoStruct オペレーションを呼び出します。

    prompt> ant build-client run

build.xml ファイルの build-client および run ターゲットを使用して、開発プロセスの一環として Java クライアント アプリケーションを繰り返し更新、再ビルド、および実行できます。

スタンドアロン Java クライアントのサンプル Ant ビルド ファイル

<project name="webservices-simple_client" default="all">
  <!-- このビルドのグローバルなプロパティを設定 -->
  <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"/>
    <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?WSDL"
/>
</java>
</target>
</project>

 


別の Web サービスからの Web サービスの呼び出し

WebLogic Web サービス内からの Web サービスの呼び出しは、「スタンドアロン クライアントからの Web サービスの呼び出し : 主な手順」で説明したスタンドアロン Java アプリケーションからの Web サービスの呼び出しに似ています。たとえば、呼び出される Web サービスの JAX-RPC スタブは clientgen Ant タスクを使用して生成しますし、Web サービス オペレーションの呼び出しに使用する Service および Port Type インスタンスも同じ標準 JAX-RPC API を使用して取得します。しかし、クライアントが J2EE コンポーネントであるかスタンドアロンであるかによって異なる点もいくつかあります。この節では、これらの相違点について説明します。

この節の説明は、読者がすでに「スタンドアロン クライアントからの Web サービスの呼び出し : 主な手順」を読んで理解していることを前提としています。また、開発環境でのクライアント アプリケーションのビルドや Java ファイルのコンパイルなどに Ant を使用していること、および別の Web サービスを呼び出すために更新する必要のある Web サービスを構築する build.xml ファイルがすでに存在していることを想定しています。

具体的には、引き続き clientgen を使用して Web サービスのクライアント部分を作成してから、jwsc を使用してこのクライアントをコンパイルして Web サービスを作成します。

以下に、build.xml ファイルで変更が必要な点を挙げます。build.xml ファイルの完全なサンプルについては、「Web サービス クライアントのサンプル build.xml ファイル」を参照してください。

以下に、クライアント Web サービスを実装する JWS ファイルで変更が必要な点を挙げます。JWS ファイルの完全なサンプルについては、「Web サービスを呼び出すサンプル JWS ファイル」を参照してください。

Web サービス クライアントのサンプル build.xml ファイル

次に示すサンプル build.xml ファイルでは、別の Web サービスを呼び出す Web サービスを作成する方法を示します。単純な Java スタンドアロン クライアントの build.xml と異なる該当部分は太字で示されています。

build-service ターゲットは、まず clientgen を呼び出して、呼び出される Web サービスの JAX-RPC スタブを生成します。コードは、一時ディレクトリに生成されます。javac タスクは、生成されたコードをクラス ファイルにコンパイルします。次に、jwsc Ant タスクがクライアント Web サービスをコンパイルします。このクライアント Web サービスの JWS ファイルには、Service および PortType インスタンスを作成して Web サービスのオペレーションを呼び出すための JAX-RPC API 呼び出しが含まれています。JWS ファイルは clientgen によって生成されたスタブをインポートするため、jwsc Ant タスクは classpathref 属性を使用してこれらのスタブが格納されている一時ディレクトリを参照します。最後に copy タスクが、clientgen によって生成されたスタブを、クライアント Web サービスを含むエンタープライズ アプリケーションの APP-INF/classes ディレクトリにコピーします。

<project name="webservices-service_to_service" default="all">
  <!-- このビルドのグローバルなプロパティを設定 -->
  <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="clientService.ear.deployed.name" value="ClientServiceEar" />
<property name="example-output" value="output" />
<property name="tempjar-dir" value="${example-output}/tempjardir" />
<property name="clientService-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>
  <path id="ws.clientService.class.path">
<pathelement path="${tempjar-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">
    <clientgen
wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
destDir="${tempjar-dir}"
packageName="examples.webservices.service_to_service"/>
    <javac
source="1.5"
srcdir="${tempjar-dir}"
destdir="${tempjar-dir}"
includes="**/*.java"/>
    <jwsc
srcdir="src"
destdir="${clientService-ear-dir}"
classpathref="ws.clientService.class.path">
        <jws
file="examples/webservices/service_to_service/ClientServiceImpl.java" />
    </jwsc>
    <copy todir="${clientService-ear-dir}/app-inf/classes">
<fileset dir="${tempjar-dir}" />
</copy>
  </target>
  <target name="deploy">
<wldeploy action="deploy" name="${clientService.ear.deployed.name}"
source="${clientService-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="${clientService.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"/>
    <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>

Web サービスを呼び出すサンプル JWS ファイル

次に示すサンプル 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;
// clientgen によって生成され、ComplexService Web サービスによって使用される
// BasicStruct データ型をインポートする
import examples.webservices.complex.BasicStruct;
// ComplexService Web サービスを呼び出すための JAX-RPC スタブをインポートする。
// 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
{
    // 複合型を呼び出すサービスとポート スタブを作成する
ComplexService service = new ComplexService_Impl(serviceUrl + "?WSDL");
ComplexPortType port = service.getComplexServicePort();
    // ComplexService の echoComplexType オペレーションを呼び出す
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 ファイルをプログラミングする際は、以下のガイドラインに従います。ガイドラインのコード例は、上述のサンプル内では太字で示されています。

 


クライアントサイド SOAP メッセージ ハンドラの作成と使用

SOAP メッセージ ハンドラの作成と使用」では、WebLogic Server で動作する Web サービスの一環として実行されるサーバサイド SOAP メッセージ ハンドラを作成する方法について説明しました。Web サービス オペレーションを呼び出すクライアント アプリケーションの一環として実行される、クライアントサイド SOAP メッセージ ハンドラを作成することもできます。クライアントサイド ハンドラの場合は、以下のタイミングで二度実行されます。

実際の Java クライアントサイド ハンドラは、サーバサイド ハンドラと同じ方法、つまり javax.xml.rpc.handler.GenericHandler 抽象クラスを拡張する Java クラスを記述する方法で作成できます。多くの場合、WebLogic Server で実行される Web サービスとその Web サービスを呼び出すクライアント アプリケーションで同じハンドラ クラスを使用できます。たとえば、サーバおよびクライアント用として、送信および受信したすべての SOAP メッセージをログに記録する汎用ロギング ハンドラ クラスを記述できます。

サーバサイド SOAP ハンドラのプログラミングと同様に、クライアントサイド SOAP メッセージ ハンドラを呼び出す clientgen Ant タスクも XML ファイルを使用して指定します。ただし、次の手順で説明するように、この XML ファイルの XML スキーマは少し異なります。

クライアントサイド SOAP メッセージ ハンドラの使用 : 主な手順

次の手順では、Web サービス オペレーションを呼び出すクライアントアプリケーションにクライアントサイド SOAP メッセージ ハンドラを追加する高度な手順を説明します。

デプロイされた Web サービスを呼び出すクライアント アプリケーションをすでに作成済みであり、クライアントサイド SOAP メッセージ ハンドラおよびハンドラ チェーンを追加することでクライアント アプリケーションを更新することを想定しています。また、Ant ベースの開発環境を設定済みであり、かつ clientgen Ant タスクを実行するためのターゲットを含む、作業用の build.xml ファイルがあることが前提となっています。詳細については、「スタンドアロン クライアントからの Web サービスの呼び出し : 主な手順」を参照してください。

  1. クライアントサイド SOAP ハンドラと、それらのハンドラの実行順序を指定するハンドラ チェーンを設計します。この手順は、視点が Web サービスからではなくクライアント アプリケーションからとなる点を除けば、サーバサイド SOAP メッセージ ハンドラを設計するのとほぼ同じ手順です。
  2. SOAP メッセージ ハンドラおよびハンドラ チェーンの設計」を参照してください。

  3. ハンドラ チェーン内の各ハンドラについて、javax.xml.rpc.handler.GenericHandler 抽象クラスを拡張する Java クラスを作成します。この手順は、チェーン内のハンドラをサーバではなくクライアントで実行する点を除けば、サーバサイド ハンドラの場合の手順と非常に似ています。
  4. ハンドラ クラスのプログラミングの詳細については、「GenericHandler クラスの作成」を参照してください。サンプルについては、「クライアントサイド ハンドラ クラスの例」を参照してください。

  5. クライアントサイド SOAP ハンドラのコンフィグレーション ファイルを作成します。この XML ファイルでは、ハンドラ チェーン内のハンドラ、ハンドラが実行される順序、送信すべき初期化パラメータなどを記述します。
  6. クライアントサイド SOAP ハンドラのコンフィグレーション ファイルの作成」を参照してください。

  7. クライアント アプリケーションのビルドに使用する build.xml ファイルを更新して、clientgen Ant タスクに SOAP ハンドラのコンフィグレーション ファイルの名前を指定します。また、build.xml によってハンドラ ファイルが Java クラスにコンパイルされ、クライアント アプリケーションで使用できる状態になることも確認する必要があります。
  8. クライアントサイド SOAP ハンドラのコンフィグレーション ファイルの clientgen への指定」を参照してください。

  9. 適切なタスクを実行して、クライアント アプリケーションを再ビルドします。
  10. prompt> ant build-client

次回クライアント アプリケーションを実行したときには、SOAP リクエスト メッセージの送信前と応答の受信後に、コンフィグレーション ファイルに記述した SOAP メッセージ ハンドラが自動的に実行されます。

clientgen Ant タスクにハンドラのコンフィグレーション ファイルが指定されている限り、クライアントサイド SOAP メッセージ ハンドラを呼び出すために実際のクライアント アプリケーションを更新する必要がない、という点が重要です。ハンドラは、生成された JAX-RPC スタブによって自動的に正しい順序で実行されます。

クライアントサイド ハンドラ クラスの例

次の例では、Web サービスを呼び出すクライアント アプリケーション用にコンフィグレーションできる単純な SOAP メッセージ ハンドラ クラスを示します。

package examples.webservices.client_handler.client;
import javax.xml.namespace.QName;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.GenericHandler;
import javax.xml.rpc.handler.MessageContext;
public class ClientHandler1 extends GenericHandler {
  private QName[] headers;
  public void init(HandlerInfo hi) {
System.out.println("in " + this.getClass() + " init()");
}
  public boolean handleRequest(MessageContext context) {
System.out.println("in " + this.getClass() + " handleRequest()");
return true;
}
  public boolean handleResponse(MessageContext context) {
System.out.println("in " + this.getClass() + " handleResponse()");
return true;
}
  public boolean handleFault(MessageContext context) {
System.out.println("in " + this.getClass() + " handleFault()");
return true;
}
  public QName[] getHeaders() {
return headers;
}
}

クライアントサイド SOAP ハンドラのコンフィグレーション ファイルの作成

クライアントサイド SOAP ハンドラのコンフィグレーション ファイルでは、ハンドラ チェーン内のハンドラのリスト、ハンドラが実行される順序、初期化パラメータなどを指定します。このファイルの詳細については、「クライアントサイド ハンドラのコンフィグレーション ファイル用 XML スキーマ」を参照してください。

このコンフィグレーション ファイルでは、1 つまたは複数のハンドラを含む 1 つのハンドラ チェーンを XML で記述します。次に単純な例を示します。

<weblogic-wsee-clientHandlerChain
xmlns="http://www.bea.com/ns/weblogic/90"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:j2ee="http://java.sun.com/xml/ns/j2ee">
        <handler>
<j2ee:handler-name>clienthandler1</j2ee:handler-name>
<j2ee:handler-class>examples.webservices.client_handler.client.ClientHandler1</j2ee:handler-class>
<j2ee:init-param>
<j2ee:param-name>ClientParam1</j2ee:param-name>
<j2ee:param-value>value1</j2ee:param-value>
</j2ee:init-param>
</handler>
        <handler>
<j2ee:handler-name>clienthandler2</j2ee:handler-name>
<j2ee:handler-class>examples.webservices.client_handler.client.ClientHandler2</j2ee:handler-class>
</handler>
</weblogic-wsee-clientHandlerChain>

この例では、ハンドラ チェーンに 2 つのハンドラ (clienthandler1 および clienthandler2) が含まれており、<j2ee:handler-class> 要素に指定されたクラス名で実装されています。これら 2 つのハンドラは、クライアント アプリケーションが SOAP リクエストを Web サービスに送信する直前に指定の順序で実行され、クライアント アプリケーションが Web サービスからの SOAP 応答を受信した直後に逆の順序で実行されます。

この例では、<j2ee:init-param> 要素を使用して 1 つまたは複数の初期化パラメータをハンドラに指定する方法も示しています。

ハンドラによって実装される SOAP ロール、ハンドラによって処理される SOAP ヘッダ、およびハンドラが関連付けられている WSDL のポート名要素を指定するには、<handler> 要素の子要素である <soap-role><soap-header>、および <port-name> をそれぞれ使用します。

クライアントサイド ハンドラのコンフィグレーション ファイル用 XML スキーマ

次の XML スキーマ ファイルでは、クライアントサイド SOAP ハンドラのコンフィグレーション ファイルの構造を定義しています。

<?xml version="1.0" encoding="UTF-8"?>
<schema
targetNamespace="http://www.bea.com/ns/weblogic/90"
xmlns:wls="http://www.bea.com/ns/weblogic/90"
xmlns:j2ee="http://java.sun.com/xml/ns/j2ee"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
>
<include schemaLocation="weblogic-j2ee.xsd"/>
  <element name="weblogic-wsee-clientHandlerChain"
type="wls:weblogic-wsee-clientHandlerChainType">
<xsd:key name="wsee-clienthandler-name-key">
<xsd:annotation>
<xsd:documentation>
            Defines the name of the handler.The name must be unique within the
chain.
            </xsd:documentation>
</xsd:annotation>
<xsd:selector xpath="j2ee:handler"/>
<xsd:field xpath="j2ee:handler-name"/>
</xsd:key>
</element>
  <complexType name="weblogic-wsee-clientHandlerChainType">
<sequence>
<xsd:element name="handler"
type="j2ee:service-ref_handlerType"
minOccurs="0" maxOccurs="unbounded">
</xsd:element>
</sequence>
</complexType>
</schema>

1 つのコンフィグレーション ファイルで、1 つのクライアントサイド ハンドラ チェーンを指定します。コンフィグレーション ファイルのルートは <weblogic-wsee-clientHandlerChain> で、ファイルにはゼロ個以上の <handler> 子要素が含まれます。これらの各子要素で、チェーン内の各ハンドラを記述します。

<handler> 要素の構造は、「J2EE 1.4 Web Service client XML Schema」で指定されている J2EE の service-ref_handlerType 複合型で記述します。

クライアントサイド SOAP ハンドラのコンフィグレーション ファイルの clientgen への指定

クライアントサイド SOAP ハンドラのコンフィグレーション ファイルを指定するには、clientgen Ant タスクの handlerChainFile 属性を使用します。次に、build.xml ファイルからの抜粋を示します。

    <clientgen
wsdl="http://ariel:7001/handlers/ClientHandlerService?WSDL"
destDir="${clientclass-dir}"
handlerChainFile="ClientHandlerChain.xml"
packageName="examples.webservices.client_handler.client"/>

clientgen によって自動的に生成された JAX-RPC スタブを使用すると、クライアント アプリケーションが Web サービス オペレーションを呼び出す前と後に、コンフィグレーション ファイルで記述されたハンドラが必ず正しい順序で実行されます。

 


クライアントサイド セキュリティ WS-Policy ファイルの使用

メッセージレベルのセキュリティ コンフィグレーションに対する WS-Policy ファイルの使い方の概要」では、Web サービスのメッセージレベルのセキュリティを記述する 1 つまたは複数の WS-Policy ファイルに、WebLogic Web サービスを関連付ける方法について説明しています。これらの WS-Policy ファイルは、SOAP メッセージのデジタル署名やデジタル暗号化の方法と、Web サービスを呼び出すクライアントで必要になるユーザ認証の種類を記述する XML ファイルです。通常、Web サービスに関連付けられた WS-Policy ファイルはその WSDL にアタッチされます。Web サービス クライアント ランタイムはこれを読み取り、クライアント アプリケーションから呼び出されたオペレーションからの SOAP メッセージ リクエストのデジタル署名やデジタル暗号化を行うかどうかを判別したり、行う場合はその方法を判別したりします。

しかし、Web サービスがデプロイ済みの WSDL に WS-Policy ファイルをアタッチしない場合や、Web サービスが WSDL をまったく公開しないようにコンフィグレーションされている場合もあります。これらの場合、Web サービス クライアント ランタイムは、SOAP メッセージ リクエストのために有効にしなければならないセキュリティをサービス自体から判別することはできません。代わりに、WS-Policy ファイルのクライアントサイドのコピーをロードする必要があります。この節では、クライアント アプリケーションを更新して、WS-Policy ファイルのローカル コピーがロードされるようにする方法について説明します。

通常、クライアントサイド WS-Policy ファイルは、デプロイ済みの Web サービスに関連付けられている WS-Policy ファイルとまったく同じものです。これら 2 つのファイルが異なり、ファイルに含まれるセキュリティ アサーションに矛盾がある場合は、Web サービス オペレーションを呼び出すとエラーが返されます。

クライアントサイド WS-Policy ファイルは、SOAP メッセージのリクエスト、応答、またはその両方に関連付けることができます。

クライアントサイド セキュリティ WS-Policy ファイルの使用 : 主な手順

次の手順では、Web サービス オペレーションを呼び出すクライアントアプリケーションに WS-Policy ファイルを関連付ける高度な手順を説明します。

デプロイされた Web サービスを呼び出すクライアント アプリケーションをすでに作成済みであり、クライアントサイド WS-Policy ファイルを関連付けることでクライアント アプリケーションを更新することを想定しています。また、Ant ベースの開発環境を設定済みであり、かつ clientgen Ant タスクを実行するためのターゲットを含む、作業用の build.xml ファイルがあることが前提となっています。詳細については、「スタンドアロン クライアントからの Web サービスの呼び出し : 主な手順」を参照してください。

  1. クライアントサイド WS-Policy ファイルを作成し、クライアント アプリケーションからアクセスできる場所に保存します。通常、この WS-Policy ファイルは、呼び出そうとしている Web サービス用にコンフィグレーションされた WS-Policy ファイルと同じものですが、サーバサイドのファイルはクライアント ランタイムに対しては公開されないため、クライアント アプリケーションは独自のローカル コピーをロードしなければなりません。
  2. WS-Policy ファイルの作成については、「カスタム WS-Policy ファイルの作成と使用」を参照してください。

    警告 : クライアント アプリケーションに対して指定できるのは、具象クライアントサイド WS-Policy ファイルのみです。抽象 WS-Policy ファイルや、あらかじめパッケージ化された 3 つのセキュリティ WS-Policy ファイルは使用できません。

  3. クライアント アプリケーションをビルドする build.xml ファイルを更新して、clientgen Ant タスクが JAX-RPC スタブ内に追加の getXXXPort() メソッドを生成するように指定します。XXX は Web サービスの名前です。これらのメソッドは、後ほどクライアント アプリケーションがクライアントサイド WS-Policy ファイルをロードする際に使用します。
  4. WS-Policy ファイルをロードするメソッドを生成するための clientgen の更新」を参照してください。

  5. Java クライアント アプリケーションを更新して、clientgen Ant タスクによって生成された追加のメソッドでクライアントサイド WS-Policy ファイルがロードされるようにします。
  6. WS-Policy ファイルをロードするためのクライアント アプリケーションの更新」を参照してください。

  7. 適切なタスクを実行して、クライアント アプリケーションを再ビルドします。次に例を示します。
  8. prompt> ant build-client

次回クライアント アプリケーションを実行したときには、WS-Policy ファイルのローカル コピーがロードされ、Web サービス クライアント ランタイムはこれを使用して SOAP リクエスト メッセージのセキュリティを有効にします。

WS-Policy ファイルをロードするメソッドを生成するための clientgen の更新

clientgen Ant タスクの generatePolicyMethods 属性を true に設定して、Ant タスクが追加の getXXX() メソッドを JAX-RPC Service インタフェースの実装内に生成するように指定し、ポートの取得時に WS-Policy ファイルのクライアントサイド コピーがロードされるようにします。次に例を示します。

    <clientgen
wsdl="http://ariel:7001/policy/ClientPolicyService?WSDL"
destDir="${clientclass-dir}"
generatePolicyMethods="true"
packageName="examples.webservices.client_policy.client"/>

生成される追加のメソッドの詳細、およびクライアント アプリケーションでのそれらのメソッドの使用方法については、「WS-Policy ファイルをロードするためのクライアント アプリケーションの更新」を参照してください。

WS-Policy ファイルをロードするためのクライアント アプリケーションの更新

clientgengeneratePolicyMethods="true" に設定すると、Ant タスクは JAX-RPC Service インタフェースの実装内に以下の追加メソッドを生成します。XXX は Web サービス ポートの名前です。

ポートを取得し、そのポートを使用したすべてのオペレーション呼び出しに WS-Policy ファイルが関連付けられるようにするには、パラメータのない通常の getXXX() メソッドの代わりにこれらのメソッドを使用します。

次の単純なクライアント アプリケーションでは、これらのポリシー メソッドの使用例を示します。コードの太字部分については、後ほど説明を加えます。

package examples.webservices.client_policy.client;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.Stub;
import java.io.FileInputStream;
import java.io.IOException;
/**
* ClientPolicyService Web サービスの <code>sayHello</code> オペレーションを呼び出す
 * 単純なスタンドアロンのクライアント アプリケーション
 *
 * @author Copyright (c) 2005 by BEA Systems.All Rights Reserved.
 */
public class Main {
  public static void main(String[] args)
throws ServiceException, RemoteException, IOException {
      FileInputStream policy_file = new FileInputStream(args[1]);
      ClientPolicyService service = new ClientPolicyService_Impl(args[0] + "?WSDL");
ClientPolicyPortType normal_port = service.getClientPolicyPort();
      ClientPolicyPortType policy_port =  service.getClientPolicyPort(policy_file, true, false);
    try {
String result = null;
result = policy_port.sayHello("Hi there!");
System.out.println( "Got result:" + result );
} catch (RemoteException e) {
throw e;
}
}
}

クライアント アプリケーションへの 2 番目の引数が WS-Policy ファイルです。アプリケーションは、このファイルから FileInputStream インスタンスを作成します。normal_port は、パラメータのない標準のメソッドを使用してポートを取得します。一方 policy_port は、追加のポリシー メソッドの 1 つを使用して、そのポートを使用したすべてのオペレーション呼び出しに WS-Policy ファイルが関連付けられるようにしています (ただし、SOAP リクエストの場合のみ)。

      ClientPolicyPortType policy_port = service.getClientPolicyPort(policy_file, true, false);

 

フッタのナビゲーションのスキップ  ページの先頭 前 次