exteNd Workbench 4.1
コアヘルプ

 

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

第10章    Webサービスコンシューマの生成

この章では、Webサービスコンシューマ(Webサービスにアクセスするプログラム)を生成する「Web Serviceウィザード」の使用について、基本手順と一般的なシナリオを説明します。トピックは次のとおりです。

For more information    Webサービスを作成する場合のウィザードの使用手順とシナリオについては、 を参照してください。

 
Top of page

基本

WorkbenchのWeb Serviceウィザードを使用すると、「Javaベースのコンシューマプログラム」に必要なコードを生成し、「標準(SOAPベース)のWebサービス」にアクセスすることができます。生成されたコードでは、背後で行われるすべてのHTTP SOAP処理を取り扱い、コンシューマプログラムでWebサービスを「Javaリモートオブジェクト」(RMIを使用)として呼び出したり、そのメソッドを呼び出したりできるようにします。

入力に対して、ウィザードでは、アクセスするWebサービスを説明する「WSDLファイル」が必要です。このファイルでは、次のようなさまざまなWebサービスの実装を処理できます。

ウィザードでは、 JAX-RPC (Java API for XML-based RPC)および jBroker Web (Novell exteNdに含まれているJAX-RPX実装)に基づいて、Javaソースファイルを生成します。JAZ-RPCは、Webサービスサポートを提供するJ2EE仕様です。

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

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

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

 
Top of page

手順

コンシューマプログラムの開発プロセスには、次の作業が含まれます。

  1. プロジェクトのセットアップによる 生成の準備

  2. ウィザードによってコンシューマコードが生成されるようにするWebサービスを説明する WSDLファイルの提供

  3. ウィザードの使用による コンシューマファイルの生成

  4. 次に対するJavaソースを含む、ウィザードによって 生成されたファイルの検査

  5. 実行するメソッド呼び出しおよび参照先Webサービスの場所を調整するための、 生成されたファイルの編集

  6. そのままの状態、または他のJavaアプリケーションにコンシューマコードを含むことによる、 生成されたファイルの使用

  7. 開発環境(テスト用)および運用環境での コンシューマプログラムの実行

 
Top of page

生成の準備

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

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

    作成すべきプロジェクトのタイプは、ウィザードによって生成されるコンシューマコードの最終的な使用方法により異なります。例は次のとおりです。

    コンシューマコードの使用方法

    作成するプロジェクト

    標準のJavaアプリケーション(ウィザードによって生成する単純なJavaクライアントクラスに基づく)

    JARプロジェクト

    J2EEアプリケーションクライアント

    CARプロジェクト

    JSPページまたはサーブレット

    WARプロジェクト

    Enterprise JavaBean

    EJB JARプロジェクト

  2. 次に示す「jBroker Webに必要なアーカイブ」を、プロジェクトに追加します。

    これらのJARは、Workbench compilelibディレクトリにあります。

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

J2EEプロジェクト」には、j2ee_api_1_n.jar (J2EEプロジェクトを作成するとWorkbenchに自動的に含まれます)も必要です。

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

 
Top of page

WSDLファイルの提供

コンシューマコードを生成するには、ターゲットWebサービスを説明するWSDLファイルをWeb Serviceウィザードに提供する必要があります。ウィザードを開始する前に、このWSDLファイルの場所またはURLを取得しておくことが推奨されます。

一般的なシナリオは次のとおりです。

 
Top of section

例: Autoloan .NET WebサービスのWSDLファイル

コンシューマコードを生成して、EMI (Equated Monthly Instalment) Calculatorという名前でXMethodsパブリックレジストリにリストされているAutoloan .NET Webサービスを使用したいとします。このWebサービスでは、特定の期間(月数)における毎月の返済額、利率、およびローン金額が計算され返されます。

この場合、 www.xmethods.netというWebサイトにアクセスすると、次の対応WSDLファイルのURLを見つけることができます。

  http://upload.eraserver.net/circle24/autoloan.asmx?wsdl

このURLを提供すると、Web ServiceウィザードではWSDKファイルを読み込み、Autoloan Webサービスについて必要な情報を取得します。

  <?xml version="1.0" encoding="utf-8"?>
  <definitions xmlns:s="http://www.w3.org/2001/XMLSchema" 
               xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
               xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" 
               xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" 
               xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
               xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
               xmlns:s0="http://circle24.com/webservices/" 
               targetNamespace="http://circle24.com/webservices/" 
               xmlns="http://schemas.xmlsoap.org/wsdl/">
    <types>
      <s:schema attributeFormDefault="qualified" elementFormDefault="qualified" 
                targetNamespace="http://circle24.com/webservices/">
        <s:element name="Calculate">
          <s:complexType>
            <s:sequence>
              <s:element minOccurs="1" maxOccurs="1" name="Months" type="s:double" />
              <s:element minOccurs="1" maxOccurs="1" name="RateOfInterest" type="s:double" />
              <s:element minOccurs="1" maxOccurs="1" name="Amount" type="s:double" />
            </s:sequence>
          </s:complexType>
        </s:element>
        <s:element name="CalculateResponse">
          <s:complexType>
            <s:sequence>
              <s:element minOccurs="1" maxOccurs="1" name="CalculateResult" nillable="true" 
                         type="s:string" />
            </s:sequence>
          </s:complexType>
        </s:element>
        <s:element name="string" nillable="true" type="s:string" />
      </s:schema>
    </types>
    <message name="CalculateSoapIn">
      <part name="parameters" element="s0:Calculate" />
    </message>
    <message name="CalculateSoapOut">
      <part name="parameters" element="s0:CalculateResponse" />
    </message>
    <message name="CalculateHttpGetIn">
      <part name="Months" type="s:string" />
      <part name="RateOfInterest" type="s:string" />
      <part name="Amount" type="s:string" />
    </message>
    <message name="CalculateHttpGetOut">
      <part name="Body" element="s0:string" />
    </message>
    <message name="CalculateHttpPostIn">
      <part name="Months" type="s:string" />
      <part name="RateOfInterest" type="s:string" />
      <part name="Amount" type="s:string" />
    </message>
    <message name="CalculateHttpPostOut">
      <part name="Body" element="s0:string" />
    </message>
    <portType name="AutoloanSoap">
      <operation name="Calculate">
        <input message="s0:CalculateSoapIn" />
        <output message="s0:CalculateSoapOut" />
      </operation>
    </portType>
    <portType name="AutoloanHttpGet">
      <operation name="Calculate">
        <input message="s0:CalculateHttpGetIn" />
        <output message="s0:CalculateHttpGetOut" />
      </operation>
    </portType>
    <portType name="AutoloanHttpPost">
      <operation name="Calculate">
        <input message="s0:CalculateHttpPostIn" />
        <output message="s0:CalculateHttpPostOut" />
      </operation>
    </portType>
    <binding name="AutoloanSoap" type="s0:AutoloanSoap">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http" 
                    style="document" />
      <operation name="Calculate">
        <soap:operation soapAction="http://circle24.com/webservices/Calculate" 
                        style="document" />
        <input>
          <soap:body use="literal" />
        </input>
        <output>
          <soap:body use="literal" />
        </output>
      </operation>
    </binding>
    <binding name="AutoloanHttpGet" type="s0:AutoloanHttpGet">
      <http:binding verb="GET" />
      <operation name="Calculate">
        <http:operation location="/Calculate" />
        <input>
          <http:urlEncoded />
        </input>
        <output>
          <mime:mimeXml part="Body" />
        </output>
      </operation>
    </binding>
    <binding name="AutoloanHttpPost" type="s0:AutoloanHttpPost">
      <http:binding verb="POST" />
      <operation name="Calculate">
        <http:operation location="/Calculate" />
        <input>
          <mime:content type="application/x-www-form-urlencoded" />
        </input>
        <output>
          <mime:mimeXml part="Body" />
        </output>
      </operation>
    </binding>
    <service name="Autoloan">
      <documentation>This Web Service mimics a Simple Autoloan calculator.</documentation>
      <port name="AutoloanSoap" binding="s0:AutoloanSoap">
        <soap:address location="http://upload.eraserver.net/circle24/autoloan.asmx" />
      </port>
      <port name="AutoloanHttpGet" binding="s0:AutoloanHttpGet">
        <http:address location="http://upload.eraserver.net/circle24/autoloan.asmx" />
      </port>
      <port name="AutoloanHttpPost" binding="s0:AutoloanHttpPost">
        <http:address location="http://upload.eraserver.net/circle24/autoloan.asmx" />
      </port>
    </service>
  </definitions>

 
Top of section

WSDLの概要

Autoloan WSDLでは、HttpGetおよびHttpPostの定義(message、portType、binding、およびservice portを含む)を無視できます。Soapの定義のみ、開発しているWebサービスコンシューマプログラムに適用されます。

このWebサービスでは、calculate()という1つのメソッドが表示されています。このメソッドは、3つのdouble (Months、RateOfInterest、およびAmount)を含むCalculateオブジェクトを取得し、1つのString (CalculateResult)を含むCalculateResponseオブジェクトを返します。Web Serviceウィザードでは、このメソッドの呼び出しをサポートするために、対応するリモートインタフェースをJavaで生成します。

typesセクションは、CalculateおよびCalculateResponseの「XMLスキーマ」定義を指定します。Web Serviceウィザードでは、これらのオブジェクトを表現するために、対応するタイプクラスをJavaで生成します。

AutoloanSoapのbindingセクションを参照すると、このWebサービスが「ドキュメントスタイル」(「RPCスタイル」ではない)として定義されていることが確認できます。これは、.NET Webサービスで一般的に見られます。バインドスタイルは、SOAPメッセージの形式を説明します。また、他のWebサービス環境との相互運用性に影響を与える場合があります。

バインドスタイル

説明

ドキュメント(リテラル使用)

SOAPメッセージの本文には、交換されるXMLドキュメントのみが含まれ、メッセージパートは、WSDLファイルのXMLスキーマでリテラルとして定義された要素にマップされます。

RPC (エンコード使用)

SOAPメッセージの本文には、指定のエンコードルールを各メッセージパートのタイプに適用することによって受信者が解釈しなければならないアドホック要素に個別ラップされた、引数および戻り値が含まれます。

Web Serviceウィザードでは、指定のバインドスタイルの処理に必要なJavaコードを生成します。

AutoloanSoapのport定義(WSDLファイルの最後)は、Webサービスにアクセスできる場所の「アドレス」(URL)を指定します(次を参照)。

  http://upload.eraserver.net/circle24/autoloan.asmx

Web Serviceウィザードでは、Webサービスを呼び出すために生成するサービスクラスおよびスタブクラスでこのURLを使用します。

 
Top of page

コンシューマファイルの生成

プロジェクトをセットアップして、適切なWSDLファイルを見つけたら、Web Serviceウィザードを使用する準備が整ったことになります。ウィザードでは一度に1つのWebサービスコンシューマが作成されるため、複数を開発する場合は、Webサービスコンシューマを複数回使用する必要があります。

ウィザードを起動するたびに、WSDLファイルおよび指定した他の入力が使用され、1セットのコンシューマソースファイルが生成されます。このプロセスの要約は次のとおりです。

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

  2. Existing Web Service]を選択して、Web Serviceウィザードを起動します。

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

    たとえば、Autoloan Webサービスのコンシューマを生成するとします。この場合、ターゲットJARプロジェクトとしてWebServiceConsumerSampleを指定し、生成されたクラスのパッケージとしてcom.exsamp.netを指定できます。

    GWSCprojloc

  4. ウィザードの指示に従って、ターゲットWebサービスを説明する「WSDLファイル」を指定します。

    たとえば、Autoloan Webサービスのコンシューマを生成する場合は、XMethodsパブリックレジストリから取得したWSDLファイルのURLを指定します。

    GWSCwsdl

  5. クラス生成およびSOAPオプション」を入力するようウィザードで要求されたら、作成するコードについての詳細を指定する必要があります。

    たとえば、これらのオプションによって、Autoloan Webサービスの適切なコンシューマソースファイル(タイプクラスを含む)が生成されます。

    GWSCoptions

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

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

 
Top of page

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

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

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

詳細

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

xxx.java    java.rmi.Remoteを拡張し、ターゲットWebサービス(WSDLファイルから決定)によって表示されるメソッドを宣言するインタフェース。生成されたスタブクラスのxxx_Stubは、Webサービスのメソッド呼び出しをサポートするためにこのインタフェースを実装します。

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

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

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

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

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

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

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

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

ウィザードによりプロジェクトが更新され、生成されたファイルがそのプロジェクトに追加されます。

 
Top of section

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

ファイル名を生成する場合、Web Serviceウィザードでは、JAX-RPCによって指定された名前付けルールに従います。Webサービスコンシューマでは、結果として付けられるファイル名は、WSDL内の定義に基づきます。

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

 
Top of section

生成の追加情報

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

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

 
Top of section

例: Autoloan .NET Webサービスの生成されたコンシューマファイル

Autoloan Webサービスに対してWeb Serviceウィザードにより生成されたコンシューマコードは、次の「Webサービスアクセスの標準ファイル」から構成されます。

また、WSDLで定義された次の「複雑なタイプをマップするためのアプリケーション固有のファイル」から構成されます。

これらのファイルは、作成すると、指定したディレクトリパスにあるプロジェクトにウィザードによって追加されます。

GWSCoutput

AutoloanSoap.java

これは、スタブクラスによって使用されるリモートインタフェースで、Autoloan Webサービスのメソッド呼び出しをサポートします。

  package com.exsamp.net;
  
  import java.rmi.Remote;
  import java.rmi.RemoteException;
  
  public interface AutoloanSoap extends Remote
  {
      com.exsamp.net.CalculateResponse calculate(com.exsamp.net.Calculate parameters) 
        throws RemoteException;
  }

Autoloan.java

これは、JAX-RPCで使用されるサービスインタフェースで、Webサービスのスタブをクライアントで取得できるようにします。

  package com.exsamp.net;
  
  import javax.xml.rpc.ServiceException;
  
  public interface Autoloan extends javax.xml.rpc.Service
  {
      public AutoloanSoap_Stub getAutoloanSoap()
          throws ServiceException;
  }

AutoloanImpl.java

これは、スタブ(AutoloanSoap_Stub)のインスタンス化を処理するサービス実装クラスです。

  package com.exsamp.net;
  
  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 AutoloanImpl
      extends com.sssw.jbroker.web.xml.rpc.ServiceImpl 
      implements Autoloan
  {
      public AutoloanImpl()
      {
          try {
              _typeMappingRegistry.importTypeMappings(_tmprops);
          } catch (Exception ex) {
              throw new javax.xml.rpc.JAXRPCException("failed to populate default type mapping registry: " + ex.getMessage());
          }
          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 AutoloanSoap_Stub getAutoloanSoap()
          throws ServiceException
      {
          try {
              return (AutoloanSoap_Stub) getPort(new QName(
                  "http://circle24.com/webservices/", "AutoloanSoap"), null, false);
          } catch (Exception ex) {
              return (AutoloanSoap_Stub) getPort(com.exsamp.net.AutoloanSoap.class);
          }
      }
      
      private void createCalls()
          throws ServiceException
      {
          Call call = null;
          
          call = createCall(new QName("http://circle24.com/webservices/", "AutoloanSoap"), 
            new QName("http://circle24.com/webservices/", "Calculate"));
          call.addParameter("{http://circle24.com/webservices/}Calculate", 
            new QName("http://circle24.com/webservices/", "Calculate"), com.exsamp.net.Calculate.class, ParameterMode.IN);
          call.addParameter("{http://circle24.com/webservices/}CalculateResponse", 
            new QName("http://circle24.com/webservices/", "CalculateResponse"), com.exsamp.net.CalculateResponse.class, ParameterMode.OUT);
          call.setReturnType(new QName("http://circle24.com/webservices/", "CalculateResponse"), com.exsamp.net.CalculateResponse.class);
          call.setProperty(Call.OPERATION_STYLE_PROPERTY, "document");
          call.setProperty(Call.ENCODINGSTYLE_URI_PROPERTY, null);
          call.setProperty(Call.SOAPACTION_URI_PROPERTY, "\"http://circle24.com/webservices/Calculate\"");
          call.setTargetEndpointAddress("http://upload.eraserver.net/circle24/autoloan.asmx");
          addCall(new QName("http://circle24.com/webservices/", "AutoloanSoap"), 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();
      static final Properties _tmprops = new Properties();
      private final Hashtable _calls = new Hashtable();
  
      static {
          _serviceName = new QName("http://circle24.com/webservices/", "com.exsamp.net.Autoloan");
          
          _intfBinding.put(AutoloanSoap.class, 
            new Binding("soap", "http://upload.eraserver.net/circle24/autoloan.asmx"));
          _portBinding.put(new QName("http://circle24.com/webservices/", "AutoloanSoap"), 
            new Binding("soap", "http://upload.eraserver.net/circle24/autoloan.asmx"));
          _intfMapping.put(AutoloanSoap.class, "com.exsamp.net.AutoloanSoap_Stub");
          _portMapping.put(new QName("http://circle24.com/webservices/",
          "AutoloanSoap"), "com.exsamp.net.AutoloanSoap_Stub");
          
          Hashtable _methodInfo;
          Hashtable _paramInfo;
          Properties _props;
          
          _methodInfo = new Hashtable();
          _paramInfo = new Hashtable();
          _props = new Properties();
          _props.setProperty("jbroker.web.soap.action","\"http://circle24.com/webservices/Calculate\"");
          _paramInfo.put("Properties", _props);
          _props = new Properties();
          _props.setProperty("jbroker.web.parameter.name", "parameters");
          _props.setProperty("jbroker.web.parameter.inout", "1");
          _paramInfo.put("Param0", _props);
          _props = new Properties();
          _props.setProperty("jbroker.web.parameter.name", "parameters");
          _props.setProperty("jbroker.web.parameter.inout", "2");
          _paramInfo.put("Result", _props);
          _methodInfo.put("Calculate", _paramInfo);
          _classInfo.put("com.exsamp.net.AutoloanSoap", _methodInfo);
          
          _tmprops.put("tm1", "com.exsamp.net.CalculateResponse com.exsamp.net.CalculateResponseMarshaler com.exsamp.net.CalculateResponseMarshaler http://circle24.com/webservices/ CalculateResponse none");
          _tmprops.put("tm0", "com.exsamp.net.Calculate com.exsamp.net.CalculateMarshaler com.exsamp.net.CalculateMarshaler http://circle24.com/webservices/ Calculate none");
      }
  }

AutoloanSoap_Stub.java

これは、スタブクラスで、メソッド呼び出しをHTTP SOAPリクエストとしてAutoloan Webサービスに渡します。

  package com.exsamp.net;
  
  import com.exsamp.net.holders.*;
  
  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 AutoloanSoap_Stub
      extends com.sssw.jbroker.web.portable.Stub
      implements AutoloanSoap
  {
      private static com.sssw.jbroker.web.QName _portType =
          new com.sssw.jbroker.web.QName("http://circle24.com/webservices/", "AutoloanSoap");
      
      private static final com.sssw.jbroker.web.Binding[] _bindings = 
          new com.sssw.jbroker.web.Binding[] {
              new com.sssw.jbroker.web.Binding("soap", "http://upload.eraserver.net/circle24/autoloan.asmx"),
      };
      
      public AutoloanSoap_Stub()
      {
          this(null);
      }
      
      public AutoloanSoap_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();
                  if (_tmprops.size() > 0) _tm.importTypeMappings(_tmprops);
              }
              _setTypeMappingRegistry(_tm);
          } catch (Exception ex) {
              throw new javax.xml.rpc.JAXRPCException("failed to initialize type mapping registry: " + ex.getMessage());
          }
      }
      
      public com.exsamp.net.CalculateResponse calculate(com.exsamp.net.Calculate _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("http://circle24.com/webservices/", "Calculate"));
              //create request
              com.sssw.jbroker.web.portable.ClientRequest out = 
                  _request("Calculate", true, "literal", true, "\"http://circle24.com/webservices/Calculate\"");
              _getDelegate().setProperty("soapAction", (Object) "\"http://circle24.com/webservices/Calculate\"");
              _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,  "http://circle24.com/webservices/", "Calculate");
              
              // do the invocation
              in = _invoke(out);
              // unmarshal the results
              
              // return
              com.exsamp.net.CalculateResponse ret = null;
              try {
                  ret = (com.exsamp.net.CalculateResponse)
                  in.readObject(com.exsamp.net.CalculateResponse.class, "http://circle24.com/webservices/", "CalculateResponse");
              } catch (java.io.EOFException eofExc) {
                  ret = null;
              }
              return ret;
              
          } catch (java.lang.Throwable t) {
              
              if (t instanceof com.sssw.jbroker.web.ServiceException) {
                  com.sssw.jbroker.web.ServiceException sex = 
                      (com.sssw.jbroker.web.ServiceException) t;
                  if (sex.getTargetException() != null)
                      t = sex.getTargetException();
              }
              
              // map to remote exception
              throw com.sssw.jbroker.web.ServiceException.mapToRemote(t);
          }
      }
      static final Properties _tmprops = new Properties();
      
      static {
          
          _tmprops.put("tm1", "com.exsamp.net.CalculateResponse com.exsamp.net.CalculateResponseMarshaler com.exsamp.net.CalculateResponseMarshaler http://circle24.com/webservices/ CalculateResponse none");
          _tmprops.put("tm0", "com.exsamp.net.Calculate com.exsamp.net.CalculateMarshaler com.exsamp.net.CalculateMarshaler http://circle24.com/webservices/ Calculate none");
      }
      
      private static Properties _rootHeaders = new Properties();
      static {
          _rootHeaders.setProperty("content-type", "text/xml; charset=UTF-8");
          _rootHeaders.setProperty("content-id", "<soapbody>");
      }
  }

AutoloanSoapClient.java

これは、(サービスオブジェクトを通じて)スタブを取得した後、そのスタブを使用してAutoloan Webサービスのcalculate()メソッドを呼び出す、単純なクライアントアプリケーションです(このメソッド呼び出しは、コメントとして生成されます。詳細については、後の 生成されたファイルの編集で説明します)。

  package com.exsamp.net;
  
  import javax.naming.*;
  
  public class AutoloanSoapClient
  {
      public void process(String[] args) throws Exception
      {
          AutoloanSoap 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.calculate(com.exsamp.net.Calculate));
  
      }
  
  
      public AutoloanSoap getRemote(String[] args) throws Exception
      {
          InitialContext ctx = new InitialContext();
          
          String lookup = "xmlrpc:soap:com.exsamp.net.Autoloan";
          Autoloan service = (Autoloan)ctx.lookup(lookup);
          AutoloanSoap remote = (AutoloanSoap)service.getAutoloanSoap();
              
          return remote;
      }
  
  
      public static void main(String[] args)
      {
          try
          {
              AutoloanSoapClient client = new AutoloanSoapClient();
              client.process(args);
          }
          catch (Exception _e)
          {
              System.out.println("*** Error Executing Generated Test Client ***");
              _e.printStackTrace();
          }
      }
  
  }

Calculate.java

このクラスは、WSDLで定義された複雑なタイプCalculateを表します。

  package com.exsamp.net;
  
  public class Calculate implements java.io.Serializable
  {
      public Calculate() {}
      
      public Calculate(double monthsVal, double rateOfInterestVal, double amountVal) {
          _months = monthsVal;
          _rateOfInterest = rateOfInterestVal;
          _amount = amountVal;
      }
      private double _months;
      public double getMonths() {
          return _months;
      }
      public void setMonths(double monthsVal) {
          _months = monthsVal;
      }
      private double _rateOfInterest;
      public double getRateOfInterest() {
          return _rateOfInterest;
      }
      public void setRateOfInterest(double rateOfInterestVal) {
          _rateOfInterest = rateOfInterestVal;
      }
      private double _amount;
      public double getAmount() {
          return _amount;
      }
      public void setAmount(double amountVal) {
          _amount = amountVal;
      }
      public java.lang.String toString()
      {
          StringBuffer buffer = new StringBuffer();
          buffer.append("{");
          buffer.append("months=" + _months);
          buffer.append(",");
          buffer.append("rateOfInterest=" + _rateOfInterest);
          buffer.append(",");
          buffer.append("amount=" + _amount);
          buffer.append("}");
          return buffer.toString();
      }
  }

CalculateMarshaler.java

このクラスは、Calculateのシリアル化および非シリアル化を処理します。

  package com.exsamp.net;
  
  import java.io.IOException;
  import org.xml.sax.Attributes;
  import com.sssw.jbroker.web.*;
  import com.sssw.jbroker.web.encoding.*;
  import com.sssw.jbroker.web.portable.InputStream;
  import com.sssw.jbroker.web.portable.OutputStream;
  
  public class CalculateMarshaler implements Marshaler
  {
      // attributes
      // elements
      private static final java.lang.String _MONTHS = "Months";
      private static final java.lang.String _RATEOFINTEREST = "RateOfInterest";
      private static final java.lang.String _AMOUNT = "Amount";
      
      public Attribute[] getAttributes(Object obj)
      {
          return null;
      }
      
      public void serialize(OutputStream os, Object obj) throws IOException
      {
          Calculate jt = (Calculate) obj;
          os.writeObject(new java.lang.Double(jt.getMonths()), _MONTHS);
          os.writeObject(new java.lang.Double(jt.getRateOfInterest()), _RATEOFINTEREST);
          os.writeObject(new java.lang.Double(jt.getAmount()), _AMOUNT);
      }
      
      public Object deserialize(InputStream is, Class javaType)
          throws IOException
      {
          if (javaType != Calculate.class)
              throw new
                  ServiceException("can\qt deserialize " + javaType.getName());
          
          try {
              // instantiate the object
              Calculate jt = (Calculate) javaType.newInstance();
              try {
                  // read elements
                  jt.setMonths(is.readDouble(_MONTHS));
                  jt.setRateOfInterest(is.readDouble(_RATEOFINTEREST));
                  jt.setAmount(is.readDouble(_AMOUNT));
              } catch (java.io.EOFException eofExc) {}
              
              return jt;
          } catch (Exception ex) {
              if (ex instanceof IOException)
                  throw (IOException) ex;
              throw new ServiceException(ex);
          }
      }
      
      public java.lang.String getMechanismType() { return null; }
  }

CalculateHolder.java

これは、Calculateのタイプマッピングサポートを実装するためにJAX-RPCによって必要とされるHolderクラスです。このクラスは、holdersサブディレクトリに生成されます。

  package com.exsamp.net.holders;
  
  import com.exsamp.net.Calculate;
  
  public final class CalculateHolder implements javax.xml.rpc.holders.Holder
  {
      public com.exsamp.net.Calculate value;
      
      public CalculateHolder() { }
      
      public CalculateHolder(com.exsamp.net.Calculate val)
      {
          value = val;
      }
  }

CalculateResponse.java

このクラスは、WSDLで定義された複雑なタイプCalculateResponseを表します。

  package com.exsamp.net;
  
  public class CalculateResponse implements java.io.Serializable
  {
      public CalculateResponse() {}
      
      public CalculateResponse(java.lang.String calculateResultVal) {
          _calculateResult = calculateResultVal;
      }
      private java.lang.String _calculateResult;
      public java.lang.String getCalculateResult() {
          return _calculateResult;
      }
      public void setCalculateResult(java.lang.String calculateResultVal) {
          _calculateResult = calculateResultVal;
      }
      public java.lang.String toString()
      {
          StringBuffer buffer = new StringBuffer();
          buffer.append("{");
          buffer.append("calculateResult=" + _calculateResult);
          buffer.append("}");
          return buffer.toString();
      }
  }

CalculateResponseMarshaler.java

このクラスは、CalculateResponseのシリアル化および非シリアル化を処理します。

  package com.exsamp.net;
  
  import java.io.IOException;
  import org.xml.sax.Attributes;
  import com.sssw.jbroker.web.*;
  import com.sssw.jbroker.web.encoding.*;
  import com.sssw.jbroker.web.portable.InputStream;
  import com.sssw.jbroker.web.portable.OutputStream;
  
  public class CalculateResponseMarshaler implements Marshaler
  {
      // attributes
      // elements
      private static final java.lang.String _CALCULATERESULT = "CalculateResult";
      
      public Attribute[] getAttributes(Object obj)
      {
          return null;
      }
      
      public void serialize(OutputStream os, Object obj) throws IOException
      {
          CalculateResponse jt = (CalculateResponse) obj;
          os.writeObject(jt.getCalculateResult(), _CALCULATERESULT);
      }
      
      public Object deserialize(InputStream is, Class javaType)
          throws IOException
      {
          if (javaType != CalculateResponse.class)
              throw new
                  ServiceException("can\qt deserialize " + javaType.getName());
          
          try {
              // instantiate the object
              CalculateResponse jt = (CalculateResponse) javaType.newInstance();
              try {
                  // read elements
                  jt.setCalculateResult((java.lang.String)is.readObject(java.lang.String.class, _CALCULATERESULT));
              } catch (java.io.EOFException eofExc) {}
              
              return jt;
          } catch (Exception ex) {
              if (ex instanceof IOException)
                  throw (IOException) ex;
              throw new ServiceException(ex);
          }
      }
      
      public java.lang.String getMechanismType() { return null; }
  }

CalculateResponseHolder.java

これは、CalculateResponseのタイプマッピングサポートを実装するためにJAX-RPCによって必要とされるHolderクラスです。このクラスは、holdersサブディレクトリに生成されます。

  package com.exsamp.net.holders;
  
  import com.exsamp.net.CalculateResponse;
  
  public final class CalculateResponseHolder implements javax.xml.rpc.holders.Holder
  {
      public com.exsamp.net.CalculateResponse value;
      
      public CalculateResponseHolder() { }
      
      public CalculateResponseHolder(com.exsamp.net.CalculateResponse val)
      {
          value = val;
      }
  }

autoloan.asmx.xmlrpc.type.mappings

このファイルで指定された設定は、CalculateおよびCalculateResponseのタイプマッピングの設定方法をjBroker Webに通知します。これらのマッピングは、データがXMLからJavaに、またはJavaからXMLに変換される場合に適用されます。

生成されたスタブおよびサービスクラスによってマッピングが自動的に設定されるため、このmappingsファイルは通常は必要ありません。これは、特別な状況(マッピングを無効にしたい場合など)のために提供されています。

mappingsファイルは、ソースツリー(src)のベースディレクトリに生成されます。

  Calculate=com.exsamp.net.Calculate com.exsamp.net.CalculateMarshaler com.exsamp.net.CalculateMarshaler http://circle24.com/webservices/ Calculate none
  CalculateResponse=com.exsamp.net.CalculateResponse com.exsamp.net.CalculateResponseMarshaler com.exsamp.net.CalculateResponseMarshaler http://circle24.com/webservices/ CalculateResponse none

 
Top of page

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

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

ガイドライン

詳細

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

  • xxxClient.java

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

  • xxxService.java

  • xxxServiceImpl.java

  • xxx_Stub.java

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

 
Top of section

xxxClient.javaファイルの編集

生成されたxxxClient.javaファイルを使用する前に、次のことを確認してください。

process()メソッド

process()メソッドでは、生成されたクライアントアプリケーションによってWebサービスのメソッドが呼び出されます。ここでは、生成されたリモートインタフェースで定義された各メソッドを呼び出して、コンソールに戻り値を表示する、コメント付きのコードを示します。例は次のとおりです。

  public void process(String[] args) throws Exception
  {
      AutoloanSoap 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.calculate(com.exsamp.net.Calculate));
  
  }

このコードは、次のように変更する必要があります。

  1. 実行する1つまたは複数のメソッド呼び出しのコメントを解除します

  2. ハードコード化された値またはランタイム時に提供されるパラメータとして、各メソッド呼び出しに適切な引数を提供します。ランタイム引数には、指定された値を検証するコードを追加することもできます。

  3. 戻りデータタイプをチェックし、toString()を使用して変換できることを確認します。toString()を使用して変換できない場合は、System.out.printlnに代わるものを使用して、返されたデータを表示します。

編集後のcalculate()メソッド呼び出しの行は、次のようになります。

  System.out.println("Autoloan Web Service\n  " + 
    "Loan input data:\n    24 months, 8%, $15000\n  " +
    "Output from the Web Service:\n    " +
    remote.calculate(new com.exsamp.net.Calculate(24, 8, 15000)));

getRemote()メソッド

この節では、getRemote()メソッドの基本的な使用方法、およびバインド情報を指定する必要がある場合のgetRemote()メソッドの修正方法について説明します。

基本的な使用方法   getRemote()メソッドでは、Webサービスへのメソッド呼び出しを処理するために、生成されたクライアントアプリケーションによってリモートオブジェクトが取得されます。このリモートオブジェクトは、生成されたスタブクラス(xxx_Stub)のインスタンスです。スタブインスタンスを作成するために、getRemote()では次のことが実行されます。

  1. JNDI検索を通じて、(サービスインタフェースxxxServiceおよび実装クラスxxxServiceImplの)サービスオブジェクトをインスタンス化します

  2. スタブを取得するためにサービスオブジェクトによって(サービスインタフェースで)提供されるメソッドを呼び出します

getRemote()に対して生成された一般的なコードの例は、次のようになります。通常は、このコードを編集する必要はありません。

  public AutoloanSoap getRemote(String[] args) throws Exception
  {
      InitialContext ctx = new InitialContext();
          
      String lookup = "xmlrpc:soap:com.exsamp.net.Autoloan";
      Autoloan service = (Autoloan)ctx.lookup(lookup);
      AutoloanSoap remote = (AutoloanSoap)service.getAutoloanSoap();
              
      return remote;
  }

バインド情報の指定   ウィザードにより、ターゲットWebサービスのバインド情報が、生成されたスタブクラス(xxx_Stub.java)およびサービス実装クラス(xxxServiceImpl.java)に含まれます。バインドでは、Webサービスにアクセスできる場所の「サービスエンドポイントアドレス」が提供されます。WSDLファイルでは、このアドレスは、soap:address location要素のURLです。

別の方法として、getRemote()メソッドでスタブインスタンスを作成する際に、使用するバインドを指定することもできます。この方法を使用すると、(Webサービスが新しい場所に移動した場合などに)スタブクラスのバインドを無効にできます。スタブのアドレスプロパティを設定するために、次のように1行のコードを追加するだけで、これを実行できます。

  public AutoloanSoap getRemote(String[] args) throws Exception
  {
      InitialContext ctx = new InitialContext();
          
      String lookup = "xmlrpc:soap:com.exsamp.net.Autoloan";
      Autoloan service = (Autoloan)ctx.lookup(lookup);
      AutoloanSoap remote = (AutoloanSoap)service.getAutoloanSoap();
  
      ((javax.xml.rpc.Stub)remote)._setProperty("javax.xml.rpc.service.endpoint.address",
        "http://upload.eraserver.net/circle24/autoloan.asmx");
  
      return remote;
  }

 
Top of page

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

この時点でのWebサービスコンシューマコードの使用方法は、開発しているアプリケーションの性質によって異なります。たとえば、場合によっては、生成されたxxxClient.javaファイルを強化してアプリケーションに含める必要があったり、xxxClient.javaから独自のクラスに構文をコピーすることだけが必要になったりします。しかし、いずれの場合でも、生成されたリモートインタフェース、サービス、およびスタブファイルが常に必要となります。

アプリケーション固有のコーディングを開始する前に、基本的なxxxClientをテストして、コンシューマコードが期待どおりに機能することを確認しておくことが推奨されます。まず、ソースファイルをコンパイルするためにプロジェクトを作成する必要があります。その後、次の節で説明するように、xxxClientを実行できます。

 
Top of page

コンシューマプログラムの実行

生成されたWebサービスコンシューマプログラムであるxxxClientは、標準のJavaアプリケーションです。このプログラムは、次のいずれかの方法で実行できます。

 
Top of section

Workbenchから

生成されたクライアントをすばやく簡単にテストできるようにするために、WorkbenchにはWeb Service Wizard Client Runnerが装備されています。この機能によって、現在のプロジェクトのクライアントアプリケーションがリストされ、実行するクライアントアプリケーションを選択できます。クライアントアプリケーションを実行するたびに、必要なファイルをすべて含むようにクラスパスが自動的に設定され、コマンドライン引数を指定できるようになります。

Procedure Client Runnerを使用する

  1. 実行するコンパイル済みのクライアントクラスを含む「プロジェクト」を開きます。

  2. Project]>[Run Web Service Client Class]の順に選択して、[Client Runner]ウィンドウを表示します。

  3. Client class to run]ドロップダウンからクライアントを選択します。

    このドロップダウンリストには、プロジェクト内でmain()メソッドを持つコンパイル済みのクラスがすべて表示されます。

  4. 次を希望する場合は、[Show command line]をオンにします。

  5. クライアントに必要なコマンドライン「引数」を入力します(各引数は、スペースを使用して区切ります)。

  6. Run]をクリックしてクライアントを実行し、ウィンドウのディスプレイコンソール部分で出力を確認します。

たとえば、生成されたAutoloanSoapClientクラスをClient Runnerを使用して実行すると、次のようになります。

GWSCrunner

AutoloanSoapClientが実行されると、Autoloan Webサービスのcalculate()メソッドが呼び出され、ローンデータ(期間、率、金額)を含むCalculateオブジェクトが渡されます。calculate()メソッドは、支払い情報の文字列を含むCalculateResponseオブジェクトを返します(これは、AutoloanSoapClientによって画面に表示されます)。

  Running com.exsamp.net.AutoloanSoapClient...
  *********************
  Autoloan Web Service
    Loan input data:
      24 months, 8%, $15000
    Output from the Web Service:
      {calculateResult=Equated Monthly Instalment (EMI) For the Amount $15000 is $678}
  *********************

 
Top of section

コマンドラインから

生成されたクライアントは、オペレーティングシステムのコマンドプロンプトから実行することもできます。この場合、必要なファイル(生成されたコンシューマクラス、jbroker-webなど)をすべて含むようにクラスパスを設定する必要があります。

クライアントのコマンドラインを表示してコピーするには、Web Service Wizard Client Runnerを使用する方法が推奨されます(前の節の説明を参照)。その後、コマンドラインをコマンドプロンプトに貼り付けて実行できます。

クライアントを他のコンピュータ(開発マシン以外)で実行する場合は、このコマンドラインにリストされるすべてのファイルにアクセスできることを確認してください。

    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.