exteNd Workbench 4.1
繧ウ繧「繝倥Ν繝�

 

    First Previous Next Last 開発ガイド  05/16/03 09:21:28 

第9章    Webサービスの生成

この章では、さまざまなソースからWebサービスを生成する「Web Serviceウィザード」の使用について、基本手順と一般的なシナリオを説明します。トピックは次のとおりです。

For more information    プログラムからWebサービスにアクセスする場合のウィザードの使用手順とシナリオについては、 を参照してください。

 
Top of page

基本

WorkbenchのWeb Serviceウィザードを使用すると、「Javaリモートオブジェクト」(RMIを使用)として実装される「標準(SOAPベース)のWebサービス」を開発することができます。ウィザードでは、 JAX-RPC (Java API for XML-based RPC)および jBroker Web (Novell exteNdに含まれているJAX-RPX実装)に基づいて、Javaソースファイルを生成します。JAZ-RPCは、Webサービスサポートを提供するJ2EE指定です。

生成されたファイルには、WebサービスへのアクセスおよびHTTP SOAPリクエストからのメソッドを処理する「サーブレット」が含まれています。生成されたファイルは、そのまま使用したり、必要に応じて変更したりできます。このJava指向の方法には、低レベルのSOAP APIをコーディングする代わりに、熟知しているRMIおよびJ2EEの技術を使用してWebサービスを処理できるという利点があります。

For more information    Webサービスの概念、標準、および技術の紹介については、 を参照してください。

For more information    ウィザードの詳細については、『ツールガイド』の章「 Web Serviceウィザード」を参照してください。

 
Top of page

手順

完全な開発プロセスには、次の作業が含まれます。

  1. 生成の準備

  2. Webサービスファイルの生成

  3. 生成されたファイルの検査

  4. 生成されたファイルの編集

  5. 生成されたファイルの使用

 
Top of section

生成の準備

Web Serviceウィザードの使用を準備するには、次の操作を行います。

  1. Workbenchで「WARプロジェクト」をセットアップします。

    生成する各Webサービスに対して、ウィザードでは、(HTTP SOAPリクエストから)そのWebサービスへのアクセスを処理する「サーブレット」を作成します。結果として、WARでは、配備するWebサービス(WARにつき1つまたは複数)を、実行場所であるJ2EEサーバにパッケージ化する必要があります。

    その他の方法は、WARで「JARサブプロジェクト」をセットアップし、このJARを使用して、Webサービスに対するサーブレットおよびその他のクラスを含めることです。いずれの場合でも、「サーブレットマッピング」がWARの配備記述子(web.xml)に含まれます。

    WSDLファイルからWebサービスを生成する場合、JARサブオブジェクトを使用する方法はWeb Serviceウィザードによって現在サポートされていません。この状況では、WARプロジェクトのみがサポートされます。

  2. 次のファイルをプロジェクトに追加します。

    ファイル

    詳細

    Webサービスが生成される元のソースファイル、クラス、またはアーカイブ

    Webサービスは、次のいずれかから生成できます。

    • JavaBeanまたはその他のJavaクラス

    • EJBセッションBean

    • Javaリモートインタフェース

    • WSDLファイル

    いずれを指定した場合でも、生成されたWebサービスで表示されるメソッドが(最低限)宣言される必要があります。

    Java ファイルをコンパイルする」    Javaファイルを指定した場合は、Web Serviceウィザードを開始する前に、プロジェクトでこれらのファイルをコンパイルする必要があります(ウィザードはコンパイルされたクラスから機能するため)。

    WSDLバインドを編集する」    WSDLファイルを指定した場合は、サービス定義のSOAPアドレスによって正しいバインドURLが指定されるように、ファイルを必要に応じて修正します。Web Serviceウィザードでは、Webサービスに対して生成するファイルでこのURLを使用します。

    jBroker Webに必要なアーカイブ:

    • ランタイム時に必要なjBroker Web APIクラスを含むjbroker-web.jar

    • XMLベースのRPCおよびSOAP処理のためのJava APIクラスを含むjaxrpc-api.jarおよびsaaj-api.jar

    • xerces.jarまたは別のXMLパーサ

    これらのJARは、Workbench compilelibディレクトリにあります。J2EEサーバの設定に基づいて、次のいずれかの操作を行います。

    • WARプロジェクトのWEB-INF/libディレクトリに追加する

    • J2EEサーバのserver classpathに追加する

    For more information    詳細については、『ツールガイド』の アーカイブ配備に関する章を参照してください。

  3. 生成、編集された後でWeb Serviceクラスをコンパイルできるように、プロジェクトの「クラスパス」を編集します。次のアーカイブを含める必要があります。

アプリケーションで「SOAPメッセージハンドラ」(高度なJAR-RPC機能)を使用する場合、プロジェクトには、activation.jar、commons-logging.jar、dom4j.jar、jaxp-api.jar、およびsaaj-ri.jarというアーカイブも必要です。これらのJARは、Workbench compilelibディレクトリにあります。

 
Top of section

Webサービスファイルの生成

WARプロジェクトをセットアップしたら、Web Serviceウィザードを使用する準備が整ったことになります。ウィザードでは、一度に1つのWebサービスが作成されるため、複数を開発する場合は、Webサービスを複数回使用する必要があります。

ウィザードを起動するたびに、作成するWebサービスの種類に関する入力が使用されます。その後、Webサービスを構成する1セットのソースファイルが生成されます。このプロセスの要約は次のとおりです。

  1. File]>[New]の順に選択して[New File]ダイアログボックスを表示し、[Web Services]タブに移動します。

  2. 次のいずれかの操作を実行して、Web Serviceウィザードを起動します。

    Webサービスの生成元

    選択するもの

    次のいずれか:

    • JavaBeanまたはその他のJavaクラス

    • EJBセッションBean

    • Javaリモートインタフェース

    New Web Service

    WSDLファイル

    Existing Web Service

    名前から分かるように、この項目は、(WSDLファイルに基づいて)配備済みのWebサービスにアクセスする「Webサービスコンシューマ」を生成するために主に使用されます。ただし、青写真としてWSDLファイルを読み込み、一致する「Webサービス」自体を生成するために使用されることもあります。

  3. プロジェクトの場所」についての情報を入力するようウィザードで要求されたら、次の項目を指定します。

    生成されたWebサービスファイルを含むようにJARプロジェクトを指定した場合、ウィザードによって、WebサービスのサーブレットをマップするWARプロジェクトを指定するよう求められます。

  4. ウィザードによってメッセージが表示されたら、Webサービスの生成元である「クラスまたはWSDLファイル」を選択します。

    その後、選択した項目に基づいて追加の情報を入力するよう求められます。

    選択項目

    ウィザードによって指定するよう求められる内容

    JavaBeanまたはその他のJavaクラス

    • 生成されたWebサービスで表示するメソッド(反対に、EJB、リモートインタフェース、またはWDSLファイルから生成した場合は、すべてのメソッドが自動的に表示されます)。

    • クラス生成およびSOAPオプション

    EJBセッションBeanのホームインタフェース

    • EJBの検索情報

    • クラス生成およびSOAPオプション

    EJBセッションBeanのリモートインタフェースまたはSessionBeanクラス自体

    • EJBセッションBeanのホームインタフェース

    • EJBの検索情報

    • クラス生成およびSOAPオプション

    Javaリモートインタフェース

    • クラス生成およびSOAPオプション

    WSDLファイル

    • クラス生成およびSOAPオプション

  5. クラス生成およびSOAPオプション」を入力するようウィザードで要求されたら、Webサービスに対して生成する1セットのソースファイルを選択して設定する必要があります。

    最も重要な選択は、「スケルトン」を「結合ベース」になるように生成するかどうかということです。この答えは、Webサービスの実装で従うアーキテクチャモデルによって異なります。 実装モデルの選択を参照してください。

    Webサービスをテストするための「スタブ」(単純なクライアントアプリケーションに付属)を生成することを選択できます。Javaクラスから生成する場合は、「WSDLファイル」(Webサービスをレジストリに発行するため)を要求したり、「バインドスタイル」(ドキュメントまたはRPC)およびWebサービスの「サービスアドレス」(URL)を指定したりすることもできます。WSDLファイルから生成する場合は、「複合タイプ」がどのようにマップされるかを指定できます。

    注記:   jBroker Web 1.xアプリケーションのサポートは、「旧製品との互換性」のオプションを使用して有効にできます。詳細については、 jBroker Web 1.xの互換性を選択した場合を参照してください。

  6. Webサービスのオプション指定が終了したら、[Finish]をクリックします。

 
Top of section

生成されたファイルの検査

ウィザードを終了すると、Webサービスに対して指定したものがすべて生成され、プロジェクトの他の部分は、サポートする変更内容で更新されます。

ウィザードによって生成されるもの

詳細

リモートインタフェースのJavaソースファイル

xxxWS.java    このファイルは、ウィザードへの入力がリモートインタフェースではない場合(JavaBean、Javaクラス、EJBセッションBean、またはWSDLファイルから開始する場合など)、自動的に生成されます。これは、Webサービスを作成するのに、(java.rmi.Remoteを拡張して、表示するメソッドを宣言する)リモートインタフェースが必要であるためです。

WSDLファイルから開始すると、生成されたリモートインタフェースの名前は、単にxxx.javaになります。

スケルトンのJavaソースファイル

xxx_ServiceSkeleton.java    (HTTP SOAPリクエストから) Webサービスへのアクセスを処理する抽象サーブレットクラス。

この結合モデルでは、xxx_ServiceTieSkeletonによってこのクラスが拡張されます。スケルトンモデルでは、(リモートインタフェースの実装時に)手動で拡張します。

結合ベースのスケルトンのJavaソースファイル

xxx_ServiceTieSkeleton.java    xxx_ServiceSkeletonを拡張する抽象サーブレットクラス。

xxxTie.java    Webサービスのフロントエンドとして結合モデルで使用されるサーブレット。(HTTP SOAPリクエストから) Webサービスへのアクセスを処理するために、xxx_ServiceTieSkeletonを拡張します。Webサービスに対するメソッド呼び出しを処理するために、次のいずれかに委任します。

  • JavaBean、Javaクラス、またはEJBセッションBeanで開始する場合、xxxTieは、xxxDelegateをインスタンス化して委任します。

  • JavaリモートインタフェースまたはWSDLファイルで開始する場合、インスタンス化して委任する独自のクラスを指定するようにxxxTie.javaファイルを編集する必要があります。

xxxDelegate.java    このファイルは、Webサービスのメソッドを実装するJavaBean、Javaクラス、またはEJBセッションBeanで開始する場合に生成されます。xxxDelegateは、この実装クラスをインスタンス化し、この実装クラスでこれらのメソッドを呼び出します。

EJBセッションBeanの場合、xxxDelegateは、リモートインタフェースオブジェクトを取得するために検索および作成を行います。その後、このオブジェクトを使用してメソッド呼び出しを実行します。

スタブのJavaソースファイル

xxxService.java    ターゲットWebサービスのスタブを取得するためにJAX-RPCクライアントによって使用されるサービスインタフェース。

xxxServiceImpl.java    スタブ(xxx_Stub)のインスタンス化を処理するサービス実装クラス。動的(スタブレス)呼び出しを含む、ターゲットWebサービスにアクセスする他の方法もサポートしています。

WSDLファイルから開始すると、サービスインタフェースおよび実装クラスに対して生成される名前は、WSDLによって異なり、Serviceというテキストが省略される場合もあります。

xxx_Stub.java    JavaベースのコンシューマからターゲットWebサービスへのメソッド呼び出しを容易にします。xxx_Stubは、各メソッド呼び出しに対して適切なHTTP SOAPリクエストを送信することによってWebサービスに対応するリモートインタフェースを実装します。

xxxClient.java    ターゲットWebサービスのコンシューマとして機能する単純なクライアントアプリケーション。(サービスオブジェクトを通じて)スタブを取得した後、そのスタブを使用してWebサービスのメソッドを呼び出します。

xxxClientは、Workbenchから([Project]>[Run Web Service Client Class]の順に選択)、またはコマンドラインから実行できます。

WSDLファイル

xxx.wsdl    Webサービスをレジストリに発行する場合に使用します。Webサービスは標準形式で説明されます。

配備記述子への更新

結合モデルでは(結合ベースのスケルトンを生成する場合)、ウィザードによってWARプロジェクトのweb.xmlファイルが更新され、WebサービスのHTTP SOAPリクエストを処理するサーブレットとしてxxxTieが宣言されます。

スケルトンモデルでは、手動でweb.xmlを編集して、使用するサーブレット(xxx_ServiceSkeletonを拡張するクラス)を宣言する必要があります。

プロジェクトコンテンツへの更新

ウィザードによりプロジェクトが更新され、生成されたファイル(および他のアプリケーション固有のファイル)がそのプロジェクトに追加されます。

プロジェクトクラスパスへの更新

ウィザードによりプロジェクトクラスパスが更新され、必要に応じてアプリケーション固有のファイルが含まれます。

生成されたファイル名について

ファイル名を生成する場合、Web Serviceウィザードでは、JAX-RPCによって指定された名前付けルールに従います。Javaクラスで開始すると、結果として生成されるファイル名は、そのクラスの名前に基づいて付けられます。WSDLで開始すると、結果として生成されるファイル名は、そのWSDLの定義に基づいて付けられます。

簡単にするため、このマニュアルでは、クラス名またはWSDL定義から派生して生成されたWebサービスのファイル名の一部を表すのにxxxを使用します。

生成の追加情報

Web Serviceウィザードでは、Webサービスのファイル(前のリストを参照)を生成する際に、背後で「jBroker Webコンパイラ」を使用します。場合によっては、次のようなアプリケーションに固有の要件をサポートするために、これらのコンパイラによって追加コードやファイルが生成されることがあります。

For more information    詳細については、 jBroker Webヘルプを参照してください。

jBroker Web 1.xの互換性を選択した場合

jBroker Webの現在のバージョンには、以前のバージョンとの高度な互換性があります。ただし、JAX-RPC標準をサポートするために導入された変更の中には、jBroker Web 1.xに由来するアプリケーションをアップグレードする場合にコード変更しなければならないものもあります。このような変更には、次に対して使用される規則が含まれています。

現在のjBroker WebおよびJAX-RPCの規則にアップグレードすることは推奨されていますが、必須ではありません。Web ServiceウィザードのjBroker Web 1.xの「互換性」オプションを使用することによって、ファイル名およびスタブアクセスに対する元のjBroker Web規則に従ってWebサービスファイルを生成できます。これにより、既存の1.xアプリケーションを変更することなく、jBroker Webの最新バージョンの他の改善点をすべて活用できるようになります。

生成された1.x互換ファイル   jBroker Web 1.xの互換性オプションを使用すると生成されるファイルについては、次の表のとおりです。

1.xの互換性オプションがオンの場合に取得されるもの

1.xの互換性オプションがオフの場合に付けられる名前

詳細

xxx_REMOTE.java

例:

  MyObject_REMOTE.java

xxxWS.java

例:

  MyObjectWS.java

生成されたリモートインタフェース

_xxx_ServiceSkeleton.java

例:

  _MyObject_REMOTE_ServiceSkeleton.java

xxx_ServiceSkeleton.java

例:

  MyObjectWS_ServiceSkeleton.java

抽象サーブレットクラス

_xxx_ServiceTieSkeleton.java

例:

  _MyObject_REMOTE_ServiceTieSkeleton.java

xxx_ServiceTieSkeleton.java

例:

  MyObjectWS_ServiceTieSkeleton.java

抽象結合サーブレットクラス

xxx_TIE.java

例:

  MyObject_TIE.java

xxxTie.java

例:

  MyObjectWSTie.java

Webサービスのサーブレット(結合モデル内)

xxx_SERVICE.java

例:

  MyObject_SERVICE.java

xxxDelegate.java

例:

  MyObjectWSDelegate.java

結合サーブレットの委任クラス

xxxService.java

例:

  MyObjectREMOTEService.java

xxxService.java

例:

  MyObjectWSService.java

スタブのサービスインタフェース

このクラスは、1.xスタイルのスタブアクセスでは使用されず、クライアントコードをJAX-RPC方法にアップグレードする場合に生成されます。

xxxServiceImpl.java

例:

  MyObjectREMOTEServiceImpl.java

xxxServiceImpl.java

例:

  MyObjectWSServiceImpl.java

スタブのサービス実装クラス

このクラスは、1.xスタイルのスタブアクセスでは使用されず、クライアントコードをJAX-RPC方法にアップグレードする場合に生成されます。

_xxx_ServiceStub.java

例:

  _MyObject_REMOTE_ServiceStub.java

xxx_Stub.java

例:

  MyObjectWS_Stub.java

Webサービスのスタブ

xxx_CLIENT.java

例:

  MyObject_CLIENT.java

xxxClient.java

例:

  MyObjectWSClient.java

Webサービスを使用するためのクライアントアプリケーション

1.x互換のクライアントでは、JNDI検索を通じてスタブを直接取得します。反対に、JAX-RPCクライアントでは、サービスオブジェクトを通じてスタブを間接的に取得します。

xxx.wsdl

例:

  MyObject_REMOTE.wsdl

xxx.wsdl

例:

  MyObjectWS.wsdl

WebサービスのWSDLファイル

 
Top of section

生成されたファイルの編集

Web Serviceウィザードによって生成されたファイルを編集する場合は、次のガイドラインに従います。

ガイドライン

詳細

編集しなければならない可能性があるファイル

編集する必要のあるファイル

編集してはいけないファイル

  • xxx_ServiceSkeleton.java

  • xxx_ServiceTieSkeleton.java

  • xxxService.java

  • xxxServiceImpl.java

  • xxx_Stub.java

生成された他のファイルは編集してもかまいませんが、通常は必要ではありません。

場合によっては、Webサービスの実装を完了するために、手動でコード化されたファイルを1つまたは複数追加して、生成されたファイルとともに使用できるようにしなければならないことがあります。 追加ファイルの作成を参照してください。

xxxTie.javaファイルの編集

生成されたxxxTie.javaファイルには、編集しなければならない可能性のあるメソッドが2つ含まれています。

init()メソッド

JavaBeanまたはJavaクラスで開始すると、xxx_ServiceTieSkeletonのsetTarget()メソッドを呼び出し、(委任する) xxxDelegateのインスタンスを渡すために、init()が生成されます。xxxDelegateによって空のコンストラクタが提供された場合、生成されたコードでは、そのコンストラクタを使用してインスタンス化を行います。

ただし、暗黙的または明示的な空のコンストラクタがない場合は、使用するコンストラクタを指定するようにコードを変更しなければなりません。また、引数を期待するコンストラクタを使用するようにコードを変更することもできます。

ウィザードでは、xxxDelegateの各パブリックコンストラクタに対してsetTarget()への呼び出しを自動的に生成します。空のコンストラクタ(存在する場合)を使用する行以外の各行は、コメントアウトされます。希望のコンストラクタのある行のコメントを解除し、関連する変更を行います。

  //super.setTarget( new MyObjectWSDelegate(  java.lang.String arg0) );
  //super.setTarget( new MyObjectWSDelegate(  java.lang.String arg0, java.lang.String arg1) );
  super.setTarget( new MyObjectWSDelegate( ) );

JavaリモートインタフェースまたはWSDLファイルで開始する場合、init()は、setTarget()呼び出しがコメントアウトされた状態で常に生成されます。この場合、インスタンス化して委任する独自のクラスを指定しなければなりません。

  //super.setTarget(new CONSTRUCT_YOUR_SERVICE_OBJECT_HERE);

EJBセッションBeanで開始する場合、生成されたinit()メソッドを編集する必要はありません。

doGet()メソッド

このメソッドは、Webサービスに送信されたHTTP GETリクエストを処理するために生成されます。このメソッドによって、WebサービスのWSDLファイル(存在する場合)が返されます。このファイルが返されない場合は、GETリクエストがサポートされていないことがユーザに通知されます。

独自のHTTP GET動作を実装する場合は、doGet()コードをカスタマイズできます。デフォルトのSOAP動作を使用する場合は、このコードを削除するか、またはコメントアウトできます。

xxxClient.javaファイルの編集

xxxClientでWebサービスをテストする前に、Webサービスの1つまたは複数のメソッドを呼び出すように、生成されたxxxClient.javaファイルを編集する必要があります。このファイルで「process()メソッド」を検索すると、考えられるメソッド呼び出しがすべてリストされたコメントが見つかります。

  // System.out.println("Test Result = " + remote.getString());
  // System.out.println("Test Result = " + remote.setString(java.lang.String));
  // System.out.println("Test Result = " + remote.sayHello());

テストするメソッド呼び出しのコメントを解除し、必要に応じて適切な引数値を指定します。

  // System.out.println("Test Result = " + remote.getString());
  System.out.println("Test Result = " + remote.setString(args[0]));
  System.out.println("Test Result = " + remote.sayHello());

For more information    生成されたxxxClient.javaファイルに対するその他の変更については、 を参照してください。

追加ファイルの作成

多くの場合、ウィザードで生成が終了すると、Webサービスに必要なJavaソースファイルがすべて使用可能になります。ただし、手動で追加のクラスをコード化しなければならない場合もあります。

次の場合

追加しなければならない内容

スケルトンモデルを使用する場合

生成されたサーブレットxxx_ServiceSkeletonを拡張し、Webサービスのリモートインタフェースを実装するクラス。手動でコード化したこのクラスは、Webサービスのサーブレットとして使用します。

結合モデルを使用し、JavaリモートインタフェースまたはWSDLファイルで開始する場合

Webサービスのリモートインタフェースを実装するクラス。手動でコードしたこのクラスをインスタンス化して委任するように、生成されたxxxTie.javaファイルを編集する必要があります。

 
Top of section

生成されたファイルの使用

ウィザードによって生成されたWebサービスファイルを使用するには、次の操作を行います。

  1. 必要に応じて、配備記述子を更新します

    結合モデルを使用する場合、ウィザードでは、WARプロジェクトのweb.xmlファイルをWebサービスの適切なサーブレットマッピングで更新します。ただし、スケルトンモデルの場合は、この情報を指定するようにweb.xmlを手動で編集する必要があります。

    次の例では、MyServiceは、WebサービスMyRemoteに対して開発者がコード化したサーブレットクラスです。

      <servlet>
         <servlet-name>MyService</servlet-name>
         <servlet-class>com.exsamp.rem.MyService</servlet-class>
      </servlet>
      
      <servlet-mapping>
         <servlet-name>MyService</servlet-name>
         <url-pattern>MyRemote</url-pattern>
      </servlet-mapping>
    
  2. 必要に応じて、プロジェクトを更新します

    ウィザードが機能するにつれて、ファイルは、必要に応じてプロジェクトのクラスパスおよびコンテンツに自動的に追加されます。ただし、コンパイルおよび実行するために必要なものがすべてプロジェクトに存在しているかどうかを自分で確認することも必要です。

    たとえば、WebサービスでEJBセッションBeanにアクセスする場合、EJBクライアントJARファイルはプロジェクトのクラスパスに存在しています。

    For more information    プロジェクトに必要なクラスパスおよびコンテンツ(jBroker Webで必要なものを含む)のセットアップの詳細については、 生成の準備を参照してください。

  3. プロジェクトを作成およびアーカイブします

    この手順を終了すると、生成したWebサービスを含むWARファイルが使用可能になります。

  4. J2EEサーバへの配備に対してセットアップします

    WARをJ2EEサーバに配備するために必要なサーバ固有の配備情報を準備します。たとえば、Novell exteNd Application Serverに配備する場合は、exteNd配備計画ファイルを作成します。

    Workbenchから配備する場合は、J2EEサーバのサーバプロファイルをセットアップする必要もあります。

  5. J2EEサーバにWARを配備します

    この手順を完了すると、WARの各Webサービスは、表示されたメソッドの標準HTTP SOAPリクエストに応答できるサーブレットとしてアクセス可能になります。

  6. J2EEサーバで実行するWebサービスをテストします

    WebサービスのxxxClientクラスを生成、編集、およびコンパイルした場合は、このクラスをメソッド呼び出しの簡単なテスト用に使用できます。WorkbenchからxxxClientを実行するには、[Project]>[Run Web Service Client Class]の順に選択します。Web Service Wizard Client Runnerが表示され、現在のプロジェクトから選択できるクライアントクラスのリストが提供されます。

    xxxClientはコマンドラインから実行することもできます(システムクラスパスに適切なディレクトリおよびアーカイブを含めた場合)。

    For more information    xxxClientの実行の詳細については、 を参照してください。

 
Top of page

実装モデルの選択

Web Serviceウィザードを使用して開発する場合に選択できる基本的な実装モデルには、2種類あります。この節では、生成するWebサービスに最も適した実装モデルを選択できるようにするこれらの実装モデルについて説明します。

 
Top of section

結合モデル

結合モデルの概要と、このモデルを使用する場合については、次のとおりです。

トピック

詳細

一般的な使用法

結合モデルは、Web Serviceウィザードへの入力として指定する「実装クラス」がある場合に、通常は使用されます。Webサービスとして表示するメソッドをすでに実装しているJavaBean、Javaクラス、またはEJBセッションBeanが、これに該当します。

機能

結合モデルでは、「委任」方法を使用して、(WebサービスのHTTP SOAP処理を取り扱う)生成されたWebサービスクラスから、(メソッド処理を取り扱う)実装クラスに、メソッド呼び出しを渡します。

利点

結合モデルを使用すると、実装クラス(ビジネス論理)と、Webサービスをサポートする生成されたインフラストラクチャクラスを区別できます。また、その他のプロトコル経由で現在アクセス可能な既存の実装クラスを再使用できるという利点もあります。

生成方法

Web Serviceウィザードでクラス生成およびSOAPオプションを指定する場合は、次のチェックボックスを両方ともオンにします。

  • [Generate skeletons]

  • [Tie-based]

生成されるファイル

JavaBean、Javaクラス、またはEJBセッションBeanで開始すると、ウィザードによって次のものが生成されます。

  • xxxWS.java (リモートインタフェース)

  • xxxDelegate.java

  • xxxTie.java

  • xxx_ServiceTieSkeleton.java

  • xxx_ServiceSkeleton.java

Web Serviceウィザードへの入力として指定するJavaリモートインタフェースまたはWSDLファイルしかない場合、この結合モデルを使用することは可能ですが、一般的ではありません。この場合、ウィザードの出力では、後で完了できるように、モデルの委任部分が残されます。その後、実装クラスをコード化し、インスタンス化して委任するように生成された結合クラスを編集する必要があります。

 
Top of section

スケルトンモデル

スケルトンモデルの概要と、このモデルを使用する場合については、次のとおりです。

トピック

詳細

一般的な使用法

スケルトンモデルは、Webサービスとして表示するメソッドが分かっていても、そのメソッドがまだ実装されていない場合に、通常は使用されます。この場合、入力としてJavaリモートインタフェースまたはWSDLファイルを指定することによって、これらのメソッドについてをWeb Serviceウィザードに通知し、生成されたWebサービスファイルのコンテキストで後にメソッドを実装します。

機能

スケルトンモデルでは、HTTP SOAP処理を取り扱うためにウィザードによって生成される「サーブレット」をサブクラスに分類することによって、Webサービスメソッドを実装します。その結果、Webサービスのロジスティクスをサポートする同じクラスによっても、メソッド呼び出しが処理されます。

利点

スケルトンモデルは比較的シンプルであり、クラスの数も少ないため、理解および維持することが簡単です。ランタイム時には、オブジェクトのオーバーヘッドが抑えられるため、パフォーマンスが向上します。

生成方法

Web Serviceウィザードでクラス生成およびSOAPオプションを指定する場合は、次のチェックボックスを両方ともオンにします。

  • [Generate skeletons]

  • [Not tie-based]

生成されるファイル

Javaリモートインタフェース」で開始する場合は、ウィザードによって次のものが生成されます。

  • xxx_ServiceSkeleton.java

WSDLファイル」で開始する場合は、ウィザードによって次のものが生成されます。

  • xxx.java (リモートインタフェース)

  • xxx_ServiceSkeleton.java

追加するファイル

ウィザードが終了したら、生成されるサーブレットxxx_ServiceSkeletonを拡張し、Webサービスのリモートインタフェースを実装するクラスをコード化する必要があります。手動でコード化したこのクラスは、Webサービスのサーブレットとして使用します。

 
Top of page

シナリオ: Javaクラスでの開始

このシナリオでは、表示するメソッドを実装する既存のJavaクラスに基づいてWebサービスを生成するために、Web Serviceウィザードをどのように使用できるかについて確認できます。

実装モデル   このシナリオでは、「結合」モデルの使用が示されています。このアーキテクチャの概要については、 実装モデルの選択を参照してください。

 
Top of section

プロジェクトセットアップ

このシナリオのWARプロジェクトは、次のようにセットアップされます。

 
Top of section

ウィザードへの入力

このシナリオでWeb Serviceウィザードに対して指定されている入力は、次のとおりです。

MyObjectクラス

MyObjectは、Webサービスの生成元となる既存のJavaクラスです。これにより、表示するメソッドが実装されます。MyObject.javaには、(ウィザードを開始する前にコンパイルする必要のある)次のコードが含まれています。

  package com.exsamp.obj;
  
  public class MyObject {
  
      private String s;
  
      public MyObject() {
      }
  
      public MyObject(String xxx) {
      }
  
      public MyObject(String xxx, String yyy) {
      }
  
      public String getString() {
          return s;
      }
  
      public boolean setString(String s) {
          this.s = s;
          return true;
      }
  
      public String sayHello() {
          return "Hello there, I am on the server";
      }
  }

プロジェクトの場所パネル

このウィザードパネルは、次のように入力が完了されます。

GWSs1projloc

クラス選択パネル

このウィザードパネルは、次のように入力が完了されます。

GWSs1objsel

メソッド選択パネル

このウィザードパネルは、次のように入力が完了されます。

GWSs1methsel

クラス生成およびSOAPオプションパネル

このウィザードパネルは、次のように入力が完了されます。

GWSs1objgen

 
Top of section

Webサービスに対して生成されたファイル

このシナリオで指定されている入力に基づいて、Web Serviceウィザードでは、Webサービスを実装するために次のファイルを生成します。

MyObjectWS.java

MyObjectWSは、Webサービスのリモートインタフェースです。ウィザードでは、これに対して次のソースコードを生成します。

  package com.exsamp.obj;
  
  import java.rmi.Remote;
  import java.rmi.RemoteException;
  
  public interface MyObjectWS extends Remote
  {
      public java.lang.String getString( )
          throws RemoteException;
  
      public boolean setString( java.lang.String arg0 )
          throws RemoteException;
  
      public java.lang.String sayHello( )
          throws RemoteException;
  }

MyObjectWS_ServiceSkeleton.java

MyObjectWS_ServiceSkeletonは、Webサービスへのアクセスを処理する抽象サーブレットクラスです。ウィザードでは、これに対して次のソースコードを生成します。

  package com.exsamp.obj;
  
  
  import java.rmi.RemoteException;
  import java.util.Properties;
  import com.sssw.jbroker.web.encoding.TypeMappingRegistry;
  import com.sssw.jbroker.web.encoding.DefaultTypeMappingRegistry;
  
  public abstract class MyObjectWS_ServiceSkeleton
      extends com.sssw.jbroker.web.portable.ServletSkeleton
      implements MyObjectWS
  {
      private static final com.sssw.jbroker.web.QName _portType =
          new com.sssw.jbroker.web.QName("urn:com.exsamp.obj.MyObject", "MyObjectWS");
      
      public MyObjectWS_ServiceSkeleton()
      {
          super(_portType);
          _setProperty("xmlrpc.schema.uri", "http://www.w3.org/2001/XMLSchema");
          _setProperty("version", "1.1");
      }
      
      private static java.util.Dictionary _atable = new java.util.Hashtable();
      static {
          _atable.put("\"urn:com.exsamp.obj.MyObject/setString\"", new java.lang.Integer(0));
          _atable.put("\"urn:com.exsamp.obj.MyObject/getString\"", new java.lang.Integer(1));
          _atable.put("\"urn:com.exsamp.obj.MyObject/sayHello\"", new java.lang.Integer(2));
      }
      
      private static java.util.Dictionary _mtable = new java.util.Hashtable();
      static {
          _mtable.put("setString", new java.lang.Integer(0));
          _mtable.put("getString", new java.lang.Integer(1));
          _mtable.put("sayHello", new java.lang.Integer(2));
      }
      
      public com.sssw.jbroker.web.portable.ServerResponse 
        _invoke(com.sssw.jbroker.web.portable.ServerRequest in) throws java.io.IOException
      {
          com.sssw.jbroker.web.portable.ServerResponse out = null;
          String soapEncURI = "soap";
          String literalURI = "literal";
          
          try {
              
              java.lang.Integer _m = null;
              String sac = in.getAction();
              if (sac != null) _m = (java.lang.Integer) _atable.get(sac);
              
              if (_m == null) {
                  sac = "\"" + sac + "\"";
                  _m = (java.lang.Integer) _atable.get(sac);
              }
              
              if (_m == null) {
                  String methodName = in.getMethod();
                  if (methodName != null) _m = (java.lang.Integer) _mtable.get(methodName);
              }
              
              if (_m == null) throw new 
                com.sssw.jbroker.web.ServiceException("unable to dispatch SOAP request");
              
              switch(_m.intValue()) {
                  
                  // setString
                  case 0: {
                      in.setEncodingStyleURI(soapEncURI);
                      java.lang.String _arg0 = null;
                      try {
                          _arg0 = (java.lang.String)
                          in.readObject(java.lang.String.class, "arg0");
                      } catch (java.io.EOFException eofExc) {
                          _arg0 = null;
                      }
                      boolean result = setString(_arg0);
                      //create reply
                      out = in.createReply();
                      //set the content type
                      java.lang.Object arg = null;
                      arg = new java.lang.Boolean(result);
                      out.writeObject(arg, "result");
                      break;
                  }
                  
                  // getString
                  case 1: {
                      in.setEncodingStyleURI(soapEncURI);
                      java.lang.String result = getString();
                      //create reply
                      out = in.createReply();
                      //set the content type
                      java.lang.Object arg = null;
                      arg = result;
                      out.writeObject(arg, "result");
                      break;
                  }
                  
                  // sayHello
                  case 2: {
                      in.setEncodingStyleURI(soapEncURI);
                      java.lang.String result = sayHello();
                      //create reply
                      out = in.createReply();
                      //set the content type
                      java.lang.Object arg = null;
                      arg = result;
                      out.writeObject(arg, "result");
                      break;
                  }
              }
              
          } catch (java.lang.Throwable ex) {
              if (System.getProperty("SOAP_DEBUG") != null) ex.printStackTrace();
              out = in.createExceptionReply();
              out.writeException(ex, "exception");
          }
          
          return out;
      }
      
      public boolean isDocument(String action)
      {
          return false;
      }
      
      
      private static Properties _rootHeaders = new Properties();
      static {
          _rootHeaders.setProperty("content-type", "text/xml; charset=UTF-8");
          _rootHeaders.setProperty("content-id", "<soapbody>");
      }
  }

MyObjectWS_ServiceTieSkeleton.java

MyObjectWS_ServiceTieSkeletonは、結合モデルをサポートするためにMyObjectWS_ServiceSkeletonを拡張する抽象クラスです。ウィザードでは、これに対して次のソースコードを生成します。

  package com.exsamp.obj;
  
  
  import java.rmi.RemoteException;
  import java.util.Properties;
  import com.sssw.jbroker.web.encoding.TypeMappingRegistry;
  import com.sssw.jbroker.web.encoding.DefaultTypeMappingRegistry;
  
  public abstract class MyObjectWS_ServiceTieSkeleton
      extends com.exsamp.obj.MyObjectWS_ServiceSkeleton
      implements com.sssw.jbroker.web.portable.TieSkeleton
  {
      private MyObjectWS _target;
      
      public void setTarget(java.rmi.Remote target)
      {
          _target = (MyObjectWS) target;
      }
      
      public java.rmi.Remote getTarget()
      {
          return _target;
      }
      
      public boolean setString(java.lang.String _arg0) 
          throws java.rmi.RemoteException
      {
          return _target.setString(_arg0);
      }
      
      public java.lang.String getString( )
          throws java.rmi.RemoteException
      {
          return _target.getString();
      }
      
      public java.lang.String sayHello( )
          throws java.rmi.RemoteException
      {
          return _target.sayHello();
      }
  }

MyObjectWSTie.java

MyObjectWSTieは、Webサービスのフロントエンドとして機能するように、抽象サーブレットクラスを拡張します。受信するリクエスト(メソッド呼び出し)を処理するために、このサーブレットは、MyObjectWSDelegateをインスタンス化して委任します。ウィザードでは、これに対して次のソースコードを生成します。

  package com.exsamp.obj;
  
  import javax.servlet.*;
  import javax.servlet.http.*;
  import java.io.*;
  
  public class MyObjectWSTie extends MyObjectWS_ServiceTieSkeleton
  {
  
      public void init() throws ServletException
      {
          try
          {
              super.init();
  
              // The following are all public constructors for the implemented service
              // class. IMPORTANT NOTE: If available, the empty constructor has been
              // implemented by default. If no implicit or explicit empty constructor
              // is available, you *must* select one from the list below and uncomment
              // it in order to construct the generated service implementation.
  
              //super.setTarget( new MyObjectWSDelegate(  java.lang.String arg0) );
              //super.setTarget( new MyObjectWSDelegate(  java.lang.String arg0, java.lang.String arg1) );
              super.setTarget( new MyObjectWSDelegate( ) );
          }
          catch (Exception _e)
          {
              throw new ServletException(_e);
          }
      }
  
  
      // The following method may be freely modified to provide custom behavior
      // when an HTTP GET request is made. Comment-out or remove this method to
      // provide default SOAP doGet functionality.
      public void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException
      {
          try
          {
              StringBuffer sb = new StringBuffer(1024);
              OutputStream out = null;
              InputStream in = null;
              String path = "/MyObjectWS.wsdl";
  
              try
              {
                  // Try to load the WSDL file.
                  in = getServletConfig().getServletContext().getResourceAsStream(path);
                  if (in == null)
                  {
                      // If it can\qt be found, return a default message.
                      sendDefaultMsg(response);
                  }
                  else
                  {
                      // Try to determine the WSDL file\qs character encoding for content-type.
                      byte[] buf = new byte[512];
                      int read = in.read(buf);
  
                      if (read <= 0)
                          sendDefaultMsg(response);
  
                      String cs = getXMLEncoding(buf);
                      StringBuffer ct = new StringBuffer(64);
                      ct.append("text/xml");
                      if (cs != null)
                      {
                          ct.append("; charset=");
                          ct.append(cs);
                      }
  
                      // Return the WSDL file.
                      response.setContentType(ct.toString());
                      out = response.getOutputStream();
                      do
                      {
                          out.write(buf, 0, read);
                      } while ((read = in.read(buf)) >= 0);
                  }
              }
              catch (Exception _e)
              {
                  throw new ServletException("Exception trying to return " + path, _e);
              }
              finally
              {
                  if (out != null)
                      out.close();
                  if (in != null) 
                      in.close();
              }
          }
          catch (Exception _e)
          {
              throw new ServletException(_e);
          }
      }
  
  
  
      // Try to determine the character encoding of this XML document.
      public static String getXMLEncoding(byte[] bytes)
      {
          String lsLine = "";
          String lsEncoding = "UTF-8";
  
          if (bytes.length >=2 && bytes[0]==0xFE && bytes[1]==0xFF)
              return "UTF-16";
          String lsState = "";
          int liDeclStart = 0;
          int liDeclLength = 0;
  
          for (int i=0; i < bytes.length; i++) 
          {
              if (lsState.equals("") && bytes[i] == \q<\q && bytes[i+1] == \q?\q) 
              {
                  lsState = "<?";
              }
              else
              {
                  if (lsState.equals("<?") && bytes[i] == \qx\q && bytes[i+1] == \qm\q
                      && bytes[i+2] == \ql\q && bytes[i+3] == \q \q)
                  {
                      liDeclStart = i;
                      lsState = "xml";
                  }
                  else
                  {
                      if (lsState.equals("xml") && bytes[i] == \q?\q && bytes[i+1] == \q>\q)
                      {
                          liDeclLength = i - liDeclStart;
                          break;
                      }
                  }
              }
          }
  
          lsLine = new String(bytes, liDeclStart, liDeclLength);
  
          int liPos = lsLine.indexOf("encoding");
          if (liPos > 0) 
          {
              lsLine = lsLine.substring(liPos + 8);
              int liEncStart = lsLine.indexOf(\q"\q);
              int liEncEnd = lsLine.indexOf(\q"\q, liEncStart +1);
              if (liEncStart < 0 && liEncEnd < 0)
              {
                  liEncStart = lsLine.indexOf("\q");
                  liEncEnd = lsLine.indexOf("\q", liEncStart +1 );
              }
  
              if (liEncStart >= 0 && liEncEnd >= 0)
                  lsEncoding = lsLine.substring(liEncStart + 1, liEncEnd);
          }
  
          return lsEncoding;
      }
  
  
  
      static private final String DEFAULT_MESSAGE = 
      "<html><head><title>Novell exteNd Web Service</title>" +
      "</head><body><h3 align=\"center\">Novell exteNd Web Service</h3>" +
      "By default, SOAP servers do not communicate via HTTP GET requests. The Novell " +
      "exteNd Web Service Wizard has generated an overloaded version of the " +
      "<i>doGet()</i> method for your convience. This method, found in your " +
      "generated _TIE code, is producing this message. If the WSDL file for this Web Service " +
      "is available in the root of your Web Service WAR, this method will return the WSDL instead " +
      "of this default message. You may add any custom code you like in your generated _TIE\qs " +
      "<i>doGet()</i> method to handle HTTP GET support.</body></html>";
  
      private void sendDefaultMsg(HttpServletResponse response) throws IOException
      {
          PrintWriter out = null;
  
          try
          {
              response.setContentType("text/html"); 
              response.setContentLength(DEFAULT_MESSAGE.length());
              out = response.getWriter();
              out.print(DEFAULT_MESSAGE);
          }
          finally 
          {
              if (out != null) out.close();
          }
      }
  }

MyObjectWSDelegate.java

MyObjectWSDelegateは、導入クラス(MyObject)をインスタンス化し、要求されたメソッド呼び出しをこのインスタンスに対して実行します。ウィザードでは、これに対して次のソースコードを生成します。

  package com.exsamp.obj;
  
  import java.rmi.Remote;
  import java.rmi.RemoteException;
  
  public class MyObjectWSDelegate implements MyObjectWS
  {
      private MyObject m_objMyObject;
  
      public MyObjectWSDelegate( java.lang.String arg0 )
      {
          m_objMyObject = new MyObject( arg0 );
      }
  
      public MyObjectWSDelegate( java.lang.String arg0, java.lang.String arg1 )
      {
          m_objMyObject = new MyObject( arg0, arg1 );
      }
  
      public MyObjectWSDelegate( )
      {
          m_objMyObject = new MyObject(  );
      }
  
      public java.lang.String getString( )
          throws RemoteException
      {
          return m_objMyObject.getString(  );
      }
  
      public boolean setString( java.lang.String arg0 )
          throws RemoteException
      {
          return m_objMyObject.setString( arg0 );
      }
  
      public java.lang.String sayHello( )
          throws RemoteException
      {
          return m_objMyObject.sayHello(  );
      }
  }

MyObjectWS.wsdl

生成されたこのファイルは、(レジストリに発行する場合に便利な)標準のWSDL形式でWebサービスを説明します。

  <?xml version="1.0" encoding="UTF-8"?>
  <definitions name="MyObjectWSService"
   targetNamespace="urn:com.exsamp.obj.MyObject"
   xmlns="http://schemas.xmlsoap.org/wsdl/"
   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:tns="urn:com.exsamp.obj.MyObject"
   xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <types/>
   <message name="setStringRequest">
    <part name="arg0" type="xsd:string"/>
   </message>
   <message name="setStringResponse">
    <part name="result" type="xsd:boolean"/>
   </message>
   <message name="getStringRequest"/>
   <message name="getStringResponse">
    <part name="result" type="xsd:string"/>
   </message>
   <message name="sayHelloRequest"/>
   <message name="sayHelloResponse">
    <part name="result" type="xsd:string"/>
   </message>
   <portType name="MyObjectWS">
    <operation name="setString" parameterOrder="arg0">
     <input message="tns:setStringRequest"/>
     <output message="tns:setStringResponse"/>
    </operation>
    <operation name="getString">
     <input message="tns:getStringRequest"/>
     <output message="tns:getStringResponse"/>
    </operation>
    <operation name="sayHello">
     <input message="tns:sayHelloRequest"/>
     <output message="tns:sayHelloResponse"/>
    </operation>
   </portType>
   <binding name="MyObjectWSBinding" type="tns:MyObjectWS">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="setString">
     <soap:operation soapAction="urn:com.exsamp.obj.MyObject/setString"/>
     <input>
      <soap:body
       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
       namespace="urn:com.exsamp.obj.MyObject" use="encoded"/>
     </input>
     <output>
      <soap:body
       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
       namespace="urn:com.exsamp.obj.MyObject" use="encoded"/>
     </output>
    </operation>
    <operation name="getString">
     <soap:operation soapAction="urn:com.exsamp.obj.MyObject/getString"/>
     <input>
      <soap:body
       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
       namespace="urn:com.exsamp.obj.MyObject" use="encoded"/>
     </input>
     <output>
      <soap:body
       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
       namespace="urn:com.exsamp.obj.MyObject" use="encoded"/>
     </output>
    </operation>
    <operation name="sayHello">
     <soap:operation soapAction="urn:com.exsamp.obj.MyObject/sayHello"/>
     <input>
      <soap:body
       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
       namespace="urn:com.exsamp.obj.MyObject" use="encoded"/>
     </input>
     <output>
      <soap:body
       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
       namespace="urn:com.exsamp.obj.MyObject" use="encoded"/>
     </output>
    </operation>
   </binding>
   <service name="MyObjectWSService">
    <port binding="tns:MyObjectWSBinding" name="MyObjectWSPort">
     <soap:address location="http://localhost/WebServiceSampleDB/WebServiceSample/MyObject"/>
    </port>
   </service>
  </definitions>

 
Top of section

テスト用に生成されたファイル

このシナリオで指定されている入力に基づいて、Web Serviceウィザードでは、配備されたWebサービスをテストできるように次のファイルを生成します。

MyObjectWSService.java

MyObjectWSServiceは、JAX-RPCで使用されるサービスインタフェースで、Webサービスのスタブをクライアントで取得できるようにします。ウィザードでは、これに対して次のソースコードを生成します。

  package com.exsamp.obj;
  
  import javax.xml.rpc.ServiceException;
  
  public interface MyObjectWSService extends javax.xml.rpc.Service
  {
      public MyObjectWS_Stub getMyObjectWSPort()
          throws ServiceException;
  }

MyObjectWSServiceImpl.java

MyObjectWSServiceImplは、スタブ(MyObjectWS_Stub)のインスタンス化を処理するサービス実装クラスです。ウィザードでは、これに対して次のソースコードを生成します。

  package com.exsamp.obj;
  
  import java.io.FileNotFoundException;
  import java.util.Iterator;
  import java.util.Hashtable;
  import java.util.Properties;
  import java.util.ArrayList;
  import java.net.URL;
  import java.net.MalformedURLException;
  import javax.xml.rpc.Call;
  import javax.xml.rpc.ParameterMode;
  import javax.xml.namespace.QName;
  import javax.xml.rpc.ServiceException;
  import com.sssw.jbroker.web.Binding;
  import com.sssw.jbroker.web.encoding.DefaultTypeMappingRegistry;
  
  public class MyObjectWSServiceImpl
      extends com.sssw.jbroker.web.xml.rpc.ServiceImpl 
      implements MyObjectWSService
  {
      public MyObjectWSServiceImpl()
      {
          try {
              createCalls();
          } catch (ServiceException ex) {
              throw new javax.xml.rpc.JAXRPCException("failed to create the call objects: " + ex.getMessage());
          }
      }
      
      public QName getServiceName() { return _serviceName; }
      
      public Iterator getPorts() { return _portMapping.keySet().iterator(); }
      
      public void setProxyMode(boolean proxy) { _proxy = proxy; }
      
      public boolean getProxyMode() { return _proxy; }
      
      public URL getWSDLDocumentLocation()
      {
          return null;
      }
      
      public java.rmi.Remote getPort(Class serviceDefInterface)
          throws ServiceException
      {
          if (serviceDefInterface == null)
              throw new ServiceException("No Service class specified.");
          if (!java.rmi.Remote.class.isAssignableFrom(serviceDefInterface))
              throw new ServiceException("Class is not a valid Interface.");
          
          String stubName = (String) _intfMapping.get(serviceDefInterface);
          Binding binding = (Binding) _intfBinding.get(serviceDefInterface);
          
          if (stubName == null)
              return getPort(serviceDefInterface, binding, 
                  _classInfo, _typeMappingRegistry, null);
          else
              return getPort(stubName, binding, _typeMappingRegistry);
      }
      
      public java.rmi.Remote getPort(QName portName, Class serviceDefInterface) 
          throws ServiceException
      {
          return getPort(portName, serviceDefInterface, getProxyMode());
      }
      
      public java.rmi.Remote getPort(QName portName, Class serviceDefInterface, boolean proxy) 
          throws ServiceException
      {
          if (((proxy==false) || (serviceDefInterface == null)) && 
              (portName != null)) {
              String stubName = (String) _portMapping.get(portName);
              Binding binding = (Binding) _portBinding.get(portName);
              
              if (stubName == null) return getPort(null, serviceDefInterface);
              
              try {
                  return getPort(stubName, binding, portName,
                     _typeMappingRegistry);
              } catch (Exception ex) {
                  return getPort(null, serviceDefInterface);
              }
          } else {
              if (serviceDefInterface == null)
                  throw new ServiceException("No Service class specified.");
              if (!java.rmi.Remote.class.isAssignableFrom(serviceDefInterface))
                  throw new ServiceException("Class is not a valid Interface.");
              
              Binding binding = (Binding) _intfBinding.get(serviceDefInterface);
              String uri = (portName == null) ? null : portName.getNamespaceURI();
              return getPort(serviceDefInterface, binding, _classInfo,
                 _typeMappingRegistry, uri);
          }
      }
      
      public Call[] getCalls(QName portName)
          throws ServiceException
      {
          ArrayList callslist = (ArrayList) _calls.get(portName);
          if (callslist == null) return null;
          Call[] calls = new Call[callslist.size()];
          return (Call[]) callslist.toArray(calls);
      }
      
      private void addCall(QName portName, Call call)
      {
          ArrayList callslist = (ArrayList) _calls.get(portName);
          if (callslist == null) {
              callslist = new ArrayList();
              _calls.put(portName, callslist);
          }
          callslist.add(call);
      }
      
      public MyObjectWS_Stub getMyObjectWSPort()
          throws ServiceException
      {
          try {
              return (MyObjectWS_Stub) getPort(new QName(
                  "urn:com.exsamp.obj.MyObject", "com.exsamp.obj.MyObjectWSPort"), null, false);
          } catch (Exception ex) {
              return (MyObjectWS_Stub) getPort(com.exsamp.obj.MyObjectWS.class);
          }
      }
      
      private void createCalls()
          throws ServiceException
      {
          Call call = null;
          
          call = createCall(new QName("urn:com.exsamp.obj.MyObject", "com.exsamp.obj.MyObjectWSPort"), 
            new QName("urn:com.exsamp.obj.MyObject", "setString"));
          call.addParameter("arg0", new QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, ParameterMode.IN);
          call.addParameter("result", new QName("http://www.w3.org/2001/XMLSchema", "boolean"), boolean.class, ParameterMode.OUT);
          call.setReturnType(new QName("http://www.w3.org/2001/XMLSchema", "boolean"), boolean.class);
          call.setProperty(Call.OPERATION_STYLE_PROPERTY, "rpc");
          call.setProperty(Call.SOAPACTION_URI_PROPERTY, "\"urn:com.exsamp.obj.MyObject/setString\"");
          call.setTargetEndpointAddress("http://localhost/WebServiceSampleDB/WebServiceSample/MyObject");
          addCall(new QName("urn:com.exsamp.obj.MyObject", "com.exsamp.obj.MyObjectWSPort"), call);
          
          call = createCall(new QName("urn:com.exsamp.obj.MyObject", "com.exsamp.obj.MyObjectWSPort"), 
            new QName("urn:com.exsamp.obj.MyObject", "getString"));
          call.addParameter("result", new QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, ParameterMode.OUT);
          call.setReturnType(new QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class);
          call.setProperty(Call.OPERATION_STYLE_PROPERTY, "rpc");
          call.setProperty(Call.SOAPACTION_URI_PROPERTY, "\"urn:com.exsamp.obj.MyObject/getString\"");
          call.setTargetEndpointAddress("http://localhost/WebServiceSampleDB/WebServiceSample/MyObject");
          addCall(new QName("urn:com.exsamp.obj.MyObject", "com.exsamp.obj.MyObjectWSPort"), call);
          
          call = createCall(new QName("urn:com.exsamp.obj.MyObject", "com.exsamp.obj.MyObjectWSPort"), 
            new QName("urn:com.exsamp.obj.MyObject", "sayHello"));
          call.addParameter("result", new QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, ParameterMode.OUT);
          call.setReturnType(new QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class);
          call.setProperty(Call.OPERATION_STYLE_PROPERTY, "rpc");
          call.setProperty(Call.SOAPACTION_URI_PROPERTY, "\"urn:com.exsamp.obj.MyObject/sayHello\"");
          call.setTargetEndpointAddress("http://localhost/WebServiceSampleDB/WebServiceSample/MyObject");
          addCall(new QName("urn:com.exsamp.obj.MyObject", "com.exsamp.obj.MyObjectWSPort"), call);
          
      }
      
      static boolean _proxy = true;
      static final QName _serviceName;
      static final Hashtable _intfMapping = new Hashtable();
      static final Hashtable _intfBinding = new Hashtable();
      static final Hashtable _portBinding = new Hashtable();
      static final Hashtable _portMapping = new Hashtable();
      static final Hashtable _classInfo = new Hashtable();
      private final Hashtable _calls = new Hashtable();
  
      static {
          _serviceName = new QName("urn:com.exsamp.obj.MyObject", "com.exsamp.obj.MyObjectWSService");
          
          _intfBinding.put(MyObjectWS.class, new Binding("soap", "http://localhost/WebServiceSampleDB/WebServiceSample/MyObject"));
          _portBinding.put(new QName("urn:com.exsamp.obj.MyObject", "com.exsamp.obj.MyObjectWSPort"), 
            new Binding("soap", "http://localhost/WebServiceSampleDB/WebServiceSample/MyObject"));
          _intfMapping.put(MyObjectWS.class, "com.exsamp.obj.MyObjectWS_Stub");
          _portMapping.put(new QName("urn:com.exsamp.obj.MyObject",
          "com.exsamp.obj.MyObjectWSPort"), "com.exsamp.obj.MyObjectWS_Stub");
          
          Hashtable _methodInfo;
          Hashtable _paramInfo;
          Properties _props;
          
          _methodInfo = new Hashtable();
          _paramInfo = new Hashtable();
          _props = new Properties();
          _props.setProperty("jbroker.web.soap.action","\"urn:com.exsamp.obj.MyObject/setString\"");
          _paramInfo.put("Properties", _props);
          _props = new Properties();
          _props.setProperty("jbroker.web.parameter.name", "arg0");
          _props.setProperty("jbroker.web.parameter.inout", "1");
          _paramInfo.put("Param0", _props);
          _props = new Properties();
          _props.setProperty("jbroker.web.parameter.name", "result");
          _props.setProperty("jbroker.web.parameter.inout", "2");
          _paramInfo.put("Result", _props);
          _methodInfo.put("setString", _paramInfo);
          _paramInfo = new Hashtable();
          _props = new Properties();
          _props.setProperty("jbroker.web.soap.action","\"urn:com.exsamp.obj.MyObject/getString\"");
          _paramInfo.put("Properties", _props);
          _props = new Properties();
          _props.setProperty("jbroker.web.parameter.name", "result");
          _props.setProperty("jbroker.web.parameter.inout", "2");
          _paramInfo.put("Result", _props);
          _methodInfo.put("getString", _paramInfo);
          _paramInfo = new Hashtable();
          _props = new Properties();
          _props.setProperty("jbroker.web.soap.action","\"urn:com.exsamp.obj.MyObject/sayHello\"");
          _paramInfo.put("Properties", _props);
          _props = new Properties();
          _props.setProperty("jbroker.web.parameter.name", "result");
          _props.setProperty("jbroker.web.parameter.inout", "2");
          _paramInfo.put("Result", _props);
          _methodInfo.put("sayHello", _paramInfo);
          _classInfo.put("com.exsamp.obj.MyObjectWS", _methodInfo);
      }
  }

MyObjectWS_Stub.java

MyObjectWS_Stubは、Webサービスにアクセスするためのプロキシとしてクライアントで使用されます。このスタブクラスは、各メソッド呼び出しのロジスティクスを処理するリモートインタフェース(MyObjectWS)を実装します。ウィザードでは、これに対して次のソースコードを生成します。

  package com.exsamp.obj;
  
  
  import java.util.Properties;
  import com.sssw.jbroker.web.core.Constants;
  import com.sssw.jbroker.web.encoding.TypeMappingRegistry;
  import com.sssw.jbroker.web.encoding.DefaultTypeMappingRegistry;
  
  public class MyObjectWS_Stub
      extends com.sssw.jbroker.web.portable.Stub
      implements MyObjectWS
  {
      private static com.sssw.jbroker.web.QName _portType =
          new com.sssw.jbroker.web.QName("urn:com.exsamp.obj.MyObject", "MyObjectWS");
      
      private static final com.sssw.jbroker.web.Binding[] _bindings = 
          new com.sssw.jbroker.web.Binding[] {
              new com.sssw.jbroker.web.Binding("soap", "http://localhost/WebServiceSampleDB/WebServiceSample/MyObject"),
      };
      
      public MyObjectWS_Stub()
      {
          this(null);
      }
      
      public MyObjectWS_Stub(DefaultTypeMappingRegistry tmr)
      {
          super(_portType, _bindings);
          _setProperty("xmlrpc.schema.uri", (Object) "http://www.w3.org/2001/XMLSchema".intern());
          _setProperty("version", (Object) "1.1");
          TypeMappingRegistry _tm = null;
          try {
              if (tmr != null)
                  _tm = tmr;
              else {
                  _tm = new DefaultTypeMappingRegistry();
              }
              _setTypeMappingRegistry(_tm);
          } catch (Exception ex) {
              throw new javax.xml.rpc.JAXRPCException("failed to initialize type mapping registry: " + ex.getMessage());
          }
      }
      
      public boolean setString(java.lang.String _arg0) 
          throws java.rmi.RemoteException
      {
          com.sssw.jbroker.web.portable.ClientResponse in = null;
          
          try {
              // create an output stream
              _getDelegate().setProperty("xmlrpc.soap.operation.name", 
                new com.sssw.jbroker.web.QName("urn:com.exsamp.obj.MyObject", "setString"));
              //create request
              com.sssw.jbroker.web.portable.ClientRequest out = 
                  _request("setString", true, "soap", false, "\"urn:com.exsamp.obj.MyObject/setString\"");
              _getDelegate().setProperty("soapAction", (Object) "\"urn:com.exsamp.obj.MyObject/setString\"");
              _getDelegate().setProperty(Constants.HTTP_CONTENT_TYPE, (Object) "text/xml; charset=utf-8");
              out._setProperties(_getDelegate().getProperties());
              Object arg = null;
              
              // marshal the parameters
              arg = _arg0;
              out.writeObject(arg, "arg0");
              
              // do the invocation
              in = _invoke(out);
              // unmarshal the results
              
              // return
              java.lang.Boolean retWrapper = (java.lang.Boolean)in.readObject(boolean.class, "result");
              boolean ret = retWrapper.booleanValue();
              return ret;
              
          } catch (java.lang.Throwable t) {
              
              // map to remote exception
              throw com.sssw.jbroker.web.ServiceException.mapToRemote(t);
          }
      }
      
      public java.lang.String getString() 
          throws java.rmi.RemoteException
      {
          com.sssw.jbroker.web.portable.ClientResponse in = null;
          
          try {
              // create an output stream
              _getDelegate().setProperty("xmlrpc.soap.operation.name", 
                new com.sssw.jbroker.web.QName("urn:com.exsamp.obj.MyObject", "getString"));
              //create request
              com.sssw.jbroker.web.portable.ClientRequest out = 
                  _request("getString", true, "soap", false, "\"urn:com.exsamp.obj.MyObject/getString\"");
              _getDelegate().setProperty("soapAction", (Object) "\"urn:com.exsamp.obj.MyObject/getString\"");
              _getDelegate().setProperty(Constants.HTTP_CONTENT_TYPE, (Object) "text/xml; charset=utf-8");
              out._setProperties(_getDelegate().getProperties());
              Object arg = null;
              
              // do the invocation
              in = _invoke(out);
              // unmarshal the results
              
              // return
              java.lang.String ret = null;
              try {
                  ret = (java.lang.String)
                  in.readObject(java.lang.String.class, "result");
              } catch (java.io.EOFException eofExc) {
                  ret = null;
              }
              return ret;
              
          } catch (java.lang.Throwable t) {
              
              // map to remote exception
              throw com.sssw.jbroker.web.ServiceException.mapToRemote(t);
          }
      }
      
      public java.lang.String sayHello() 
          throws java.rmi.RemoteException
      {
          com.sssw.jbroker.web.portable.ClientResponse in = null;
          
          try {
              // create an output stream
              _getDelegate().setProperty("xmlrpc.soap.operation.name", 
                new com.sssw.jbroker.web.QName("urn:com.exsamp.obj.MyObject", "sayHello"));
              //create request
              com.sssw.jbroker.web.portable.ClientRequest out = 
                  _request("sayHello", true, "soap", false, "\"urn:com.exsamp.obj.MyObject/sayHello\"");
              _getDelegate().setProperty("soapAction", (Object) "\"urn:com.exsamp.obj.MyObject/sayHello\"");
              _getDelegate().setProperty(Constants.HTTP_CONTENT_TYPE, (Object) "text/xml; charset=utf-8");
              out._setProperties(_getDelegate().getProperties());
              Object arg = null;
              
              // do the invocation
              in = _invoke(out);
              // unmarshal the results
              
              // return
              java.lang.String ret = null;
              try {
                  ret = (java.lang.String)
                  in.readObject(java.lang.String.class, "result");
              } catch (java.io.EOFException eofExc) {
                  ret = null;
              }
              return ret;
              
          } catch (java.lang.Throwable t) {
              
              // map to remote exception
              throw com.sssw.jbroker.web.ServiceException.mapToRemote(t);
          }
      }
      
      
      private static Properties _rootHeaders = new Properties();
      static {
          _rootHeaders.setProperty("content-type", "text/xml; charset=UTF-8");
          _rootHeaders.setProperty("content-id", "<soapbody>");
      }
  }

MyObjectWSClient.java

MyObjectWSClientは、次の方法でWebサービスにアクセスする単純なクライアントアプリケーションです。

  1. JNDI検索を通じてMyObjectWSServiceをインスタンス化する

  2. スタブ(MyObjectWS_Stub)を取得するためにMyObjectWSServiceオブジェクトを使用する

  3. MyObjectWS_Stubオブジェクトを通じてWebサービスメソッドを呼び出す

ウィザードでは、これに対して次のソースコードを生成します。

  package com.exsamp.obj;
  
  import javax.naming.*;
  
  public class MyObjectWSClient
  {
      public void process(String[] args) throws Exception
      {
          MyObjectWS remote = getRemote(args);
  
          // The following code has been generated for your testing convenience. ln
          // order to successfully test your Web Service, you must uncomment one or
          // more of these lines and supply meaningful arguments where necessary.
          // Once you have modified the test method(s) below, compile this class and
          // execute it from a command line with your class path set appropriately.
  
          // System.out.println("Test Result = " + remote.getString());
          // System.out.println("Test Result = " + remote.setString(java.lang.String));
          // System.out.println("Test Result = " + remote.sayHello());
  
      }
  
  
      public MyObjectWS getRemote(String[] args) throws Exception
      {
          InitialContext ctx = new InitialContext();
          
          String lookup = "xmlrpc:soap:com.exsamp.obj.MyObjectWSService";
          MyObjectWSService service = (MyObjectWSService)ctx.lookup(lookup);
          MyObjectWS remote = (MyObjectWS)service.getMyObjectWSPort();
              
          return remote;
      }
  
  
      public static void main(String[] args)
      {
          try
          {
              MyObjectWSClient client = new MyObjectWSClient();
              client.process(args);
          }
          catch (Exception _e)
          {
              System.out.println("*** Error Executing Generated Test Client ***");
              _e.printStackTrace();
          }
      }
  
  }

必要な変更   生成されたMyObjectWSClient.javaファイルのprocess()メソッドは、テストするWebサービスメソッド呼び出しのコメントを解除するように編集する必要があります。変更内容は次のとおりです。

  // System.out.println("Test Result = " + remote.getString());
  // System.out.println("Test Result = " + remote.setString(java.lang.String));
  System.out.println("Test Result = " + remote.sayHello());

 
Top of section

配備記述子

このシナリオでは結合モデルが使用されるため、Web Serviceウィザードによってweb.xmlファイルが自動的に更新され、MyObject Webサービスのリクエストを処理するサーブレットクラスとしてMyObjectWSTieが宣言されます。

  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
                           "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
  <web-app>
      <servlet>
          <servlet-name>MyObject</servlet-name>
          <servlet-class>com.exsamp.obj.MyObjectWSTie</servlet-class>
      </servlet>
      <servlet-mapping>
          <servlet-name>MyObject</servlet-name>
          <url-pattern>MyObject</url-pattern>
      </servlet-mapping>
  </web-app>

 
Top of section

ランタイムテストの結果

このプロジェクトを作成した後、WARファイルが作成されてJ2EEサーバに配備されると、MyObject Webサービスのテストを実行する準備が整ったことになります。MyObjectWSClientアプリケーションを実行するためにWorkbenchでClient Runnerを使用した場合の結果は、次のとおりです。

GWSs1runner

    First Previous Next Last 開発ガイド  05/16/03 09:21:28 

Copyright © 1997, 1998, 1999, 2000, 2001, 2002, 2003 SilverStream Software, LLC, a wholly owned subsidiary of Novell, Inc. All rights reserved.