ヘッダーをスキップ
Oracle SOA Suite開発者ガイド
10g(10.1.3.1.0)
B31839-01
  目次へ
目次
索引へ
索引

前へ
前へ
 
次へ
次へ
 

9.6 Webサービスで使用するデータの収集

SOAシステムでは、外部アプリケーションで使用するデータの収集が必要になる場合があります。 たとえば、受注記帳システムでは、SOADEMO-CLIENTアプリケーションで顧客情報が収集され、この情報が外部の顧客サービス・アプリケーションに渡されて、新規の顧客が作成されます。

SOAシステム内のアプリケーションとコンポーネントは、通常はWSDLを使用して、パブリックなサービス・インタフェースを公開する必要があります。 したがって、Webクライアントは、アプリケーション・コンポーネント(RMIを使用)またはWebサービス・インタフェースのいずれかと相互に作用します。 Webサービスを介した相互作用では、提供されているWSDLを使用してWebサービスのサービス・プロキシを作成することで、ページで収集する必要があるデータ(例: 属性の名前とタイプ)を決定できます。

サービスのメソッドで単純なデータ型をパラメータとして取る場合は、データの表示用に作成するフォームと同様に、ADFデータ・バインディングを使用してデータを収集するフォームを作成できます。 最初に、提供されているWSDLに基づいて、データ・コントロールを作成します。 手順については、第5.3.3項「Webサービスからのデータ・コントロールの作成方法」を参照してください。 次の項の説明に従って、メソッド自体(メソッドの戻りとは逆に)をドロップして入力フォームを作成します。

メソッドで、ADFデータ・バインディングを使用せずに、複雑なオブジェクトをパラメータとして取る場合は、データを収集してサービスに渡すロジックを作成する必要があります。 このロジックは、ページのバッキングBeanに追加します。 手順については、第9.6.3項「バッキングBeanを使用したサービスの起動方法」を参照してください。

9.6.1 Webサービスのデータ・コントロールを使用した入力フォームの作成方法

既存のデータを表示する場合のようにメソッドからの戻りをドラッグするかわりに、メソッド自体をドラッグしてパラメータ化されたフォームを作成します。


注意:

データ・コントロールは、複雑なオブジェクトの作成には使用できません。 たとえば、受注記帳アプリケーションに対してCustomerオブジェクトを作成するには、Addressオブジェクトも作成する必要があります。 このためには、バッキングBeanからサービスを手動で起動する必要があります。 詳細は、第9.6.3項「バッキングBeanを使用したサービスの起動方法」を参照してください。

ADF入力フォームを作成する手順は、次のとおりです。

  1. ビジュアル・エディタでJSFページを開きます。

  2. データ・コントロール・パレットから、適切な操作をJSFページまでドラッグします。

  3. ポップアップ・メニューから、「パラメータ」「ADFパラメータ・フォーム」の順に選択します。

    「フォーム・フィールドの編集」ダイアログが開きます。このダイアログでは、フォームの作成前にラベル、バインディングおよびUIコンポーネントをカスタマイズできます。 JDeveloperでは、メソッドにバインドするコマンド・ボタンが自動的に追加されます。このメソッドによって、Webサービスが起動し、フォームで取得されたデータが送信されます。

9.6.2 ADF入力フォーム作成時の処理内容

操作をパラメータ・フォームとしてドロップすると、JDeveloperでは次の処理が実行されます。

  • データ値を保持する変数、操作用のメソッド・バインディング、およびページ定義ファイル内の関連する属性に対する属性バインディングが定義されます。

  • ADF Faces inputTextコンポーネントおよびADF Facesコマンド・ボタン・コンポーネントを使用して、コードがフォームのJSFページに挿入されます。 このコードは、他の入力フォームやコマンド・ボタン用のコードと同じです。

パラメータ・フォームを作成すると、JDeveloperでは、パラメータごとにNamedData要素が作成されます。 パラメータ値はユーザーが指定するため、各NamedData要素は、対応する属性に対する属性バインディングにバインドされます。 このバインディングによって、実行時の操作では、パラメータの属性値へのアクセスが可能になります。

コレクションの属性と同様に、メソッドの属性もイテレータを参照します。 ただし、関連するメソッドが戻すコレクションにアクセスして処理を繰り返すメソッド・イテレータを参照するかわりに、作成タイプ・メソッドの属性が変数にアクセスして処理を繰り返します。 このタイプのメソッドはオブジェクトを戻さないため、ページに入力された値を保持する変数はありません。 変数は、データ・ホルダーとして機能します。

JDeveloperでは、メソッドが取るパラメータごとに変数が作成されます。 この変数は変数イテレータの子として宣言され、ローカル変数であるため、関連するバインディング・コンテキストの存続期間中のみ存続します。 例9-9に、CustomerSvc WSDLで作成されたデータ・コントロールからaddNewCustomer操作を使用して作成された、変数イテレータと変数を示します。 これはデモ用であるため、フォームの作成に必ずしもすべての属性が使用されているわけではありません。

例9-9 変数および変数イテレータ

<executables>
  <variableIterator id="variables">
    <variable Type="java.lang.String" Name="addNewCustomer_customer_fname"
              IsQueriable="false"/>
    <variable Type="java.lang.String" Name="addNewCustomer_customer_lname"
              IsQueriable="false"/>
    <variable Type="java.lang.String" Name="addNewCustomer_customer_email"
              IsQueriable="false"/>
  </variableIterator>
</executables>

ユーザーがデータを入力してフォームを発行すると、変数が移入され、属性バインディングによってメソッドのパラメータの値が提供されます。 例9-10では、メソッド・パラメータはNamedData要素で、この要素では属性バインディングを評価するEL式が使用されています。 属性バインディングは、その値に対する変数を参照します。

例9-10 NamedData要素を使用して値を提供するメソッド・パラメータ

<bindings>
  <methodAction id="addNewCustomer" MethodName="addNewCustomer"
                RequiresUpdateModel="true" Action="999"
                IsViewObjectMethod="false" DataControl="CustomerSvc"
                InstanceName="CustomerSvc"
         ReturnName="CustomerSvc.methodResults.CustomerSvc_addNewCustomer_result">
    <NamedData NDName="customer_lname" NDType="java.lang.String"
               NDValue="${bindings.addNewCustomer_customer_lname}"/>
    <NamedData NDName="customer_fname" NDType="java.lang.String"
               NDValue="${bindings.addNewCustomer_customer_fname}"/>
    <NamedData NDName="customer_email" NDType="java.lang.String"
               NDValue="${bindings.addNewCustomer_customer_email}"/>
  </methodAction>
  <attributeValues id="customer_fname" IterBinding="variables">
    <AttrNames>
      <Item Value="addNewCustomer_customer_fname"/>
    </AttrNames>
  </attributeValues>
  <attributeValues id="customer_lname" IterBinding="variables">
    <AttrNames>
      <Item Value="addNewCustomer_customer_lname"/>
    </AttrNames>
  </attributeValues>
  <attributeValues id="customer_email" IterBinding="variables">
    <AttrNames>
      <Item Value="addNewCustomer_customer_email"/>
    </AttrNames>
  </attributeValues>
</bindings>

ADFパラメータ・フォームの使用方法は、『Oracle Application Development Framework開発者ガイド』を参照してください。

9.6.3 バッキングBeanを使用したサービスの起動方法

Webサービスを直接起動する必要があるときに、データ・コントロールを使用できない場合があります。 このような場合は、この操作を実行するロジックをページのバッキングBeanに作成します。 たとえば、SOADEMO-CLIENTアプリケーションでは、データを収集してサービスに送信するすべてのロジックがRegister.javaバッキングBeanに作成されています。

コンポーネントをページに簡単にバインドするためには、JSFページの作成時に自動コンポーネント・バインディング機能を使用できます。 この機能は、各コンポーネントをバッキングBeanのプロパティに自動的にバインドします。 次に、コマンド・コンポーネントにバインドされているメソッドにロジックを追加します。このコマンド・コンポーネントによって、データがWebサービスに送信されます。

ADFデータ・バインディングを使用せずにサービスを起動する手順は、次のとおりです。

  1. 第9.3.1項「JSF Webページの作成方法」の手順に従って、JSFページを作成します。 ただし、手順7で、「新規マネージドBeanでのUIコンポーネントの自動公開」オプションを選択してください。 ウィザードのこの手順の詳細は、「ヘルプ」をクリックしてください。

  2. 図9-19に示すように、コンポーネント・パレットのドロップダウン・メニューから「ADF Faces Core」を選択します。 これによって、ADF FacesコンポーネントをJSFページまでドラッグできます。

    図9-19 コンポーネント・パレットでのタグ・ライブラリの選択

    コンポーネント・パレットのタグ・ライブラリ

  3. InputTextコンポーネントを、コンポーネント・パレットからページまでドラッグします。

    自動コンポーネント・バインディングを使用しているため、ページにドロップした各コンポーネントは、バッキングBeanのプロパティに自動的にバインドされます。

    LabelAutoSubmitDisabledなどのコンポーネント・プロパティが設定されます。 これらのプロパティは必要に応じて変更できます。 ADF Facesの各プロパティの詳細は、JDeveloperのオンライン・ヘルプを参照してください。

  4. デフォルトでは、コンポーネントには、inputText1などのコンポーネント・タイプに基づいてIDが設定されます。 このIDを、関連するWSDLの対応する要素名と同じ名前に変更します。

    たとえば、例9-11に、CustomerService WSDLでの顧客の要素を示します。

    例9-11 WSDLでの要素定義

    <complexType name="Customer">
      <sequence>
        <element name="password" type="string" nillable="true" />
        <element name="lname" type="string" nillable="true" />
        <element name="phonenumber" type="string" nillable="true" />
        <element name="fname" type="string" nillable="true" />
        <element name="addressList" type="ns1:list" nillable="true" />
        <element name="creditcardtype" type="string" nillable="true" />
        <element name="email" type="string" nillable="true" />
        <element name="status" type="string" nillable="true" />
        <element name="creditcardnumber" type="string" nillable="true" />
        <element name="custid" type="string" nillable="true" />
      </sequence>
    </complexType>
    
    

    lname要素に対するinputTextコンポーネントを作成するには、そのコンポーネントのIDをlnameに変更します。

  5. 対応するバッキングBeanにコードを追加してデータを収集し、Webサービスを起動します。

    ページには入力コンポーネント用のgetterおよびsetterメソッドがすでにあるため、記述する必要があるのは、該当するデータを使用して新規オブジェクトを作成するコードのみです。 例9-12に、顧客オブジェクトとアドレス・オブジェクトを作成するコードを示します。

    Webサービスには、プロキシの作成時に生成されたクライアントを使用してアクセスします(第5.3.1項「Webサービス・プロキシの作成方法」を参照)。 このメソッドは、最初にユーザーを認可済ユーザーとして設定し、パスワードとして入力されたデータがパスワード・チェック・コンポーネントと同じであることを確認し、Webサービスにアクセスして顧客を作成します。


    ヒント:

    使用するクラスはプロキシからインポートする必要があります。 たとえば、例9-12では、CustomerクラスとAddressクラスをインポートする必要があります。

    例9-12 顧客を作成してCustomerService Webサービスを起動するためのコード

    public void register_action(ActionEvent ae) {
      String AUTH_USER = "Authorized_User";
      FacesContext ctx = FacesContext.getCurrentInstance();
      Customer newCust = new Customer();
      if (password.getValue().toString().equals(password
                                          _chk.getValue().toString())) {
    
        // Call Web service to register new customer
         try {
               oracle.soademo.view.services.CustomerServiceClient myPort = new
                       oracle.soademo.view.services.CustomerServiceClient();
               System.out.println("calling " + myPort.getEndpoint());
    
                 // Adding new customer info
                    Address addr = new Address();
    
                    newCust.setFname(fname.getValue().toString());
                    newCust.setLname(lname.getValue().toString());
                    newCust.setEmail(email.getValue().toString());
                    newCust.setPhonenumber(phone.getValue().toString());
                    newCust.setPassword(password.getValue().toString());
    
                    addr.setStreet(street.getValue().toString());
                    addr.setCity(city.getValue().toString());
                    addr.setState(state.getValue().toString());
                    addr.setZip(zip.getValue().toString());
    
                    List addrList = new ArrayList();
                    addrList.add(addr);
                    newCust.setAddressList(addrList);
    
                    // Call Customer WS to add customer -
                              returns customer id of new customer (newCustId)                newCustId = myPort.addNewCustomer(newCust);                                  // Retrieve complete customer object using WS
                           newCust = myPort.findCustomerById(newCustId);
    
                 // Generate successful registration message..
                    FacesContext.getCurrentInstance().addMessage(null, new
                           FacesMessage("Registration Successful!"));
    
           } catch (Exception ex) {
              FacesMessage msg = new FacesMessage("Registration Failed!");
              msg.setSeverity(msg.SEVERITY_ERROR);
              FacesContext.getCurrentInstance().addMessage(null, msg);
              FacesContext.getCurrentInstance().addMessage(null, new
                        FacesMessage(ex.getMessage()));
               ex.printStackTrace();
    
       }
    
    
  6. コンポーネント・パレットからコマンド・ボタンをドラッグします。

    このボタンは、作成したメソッドを起動するために使用します。

  7. コマンド・ボタンを選択し、プロパティ・インスペクタのドロップダウン・メニューから、作成したメソッドを選択します。

    これによって、コマンド・ボタンがメソッドにバインドされます。 このメソッドは、ユーザーがボタンをクリックすると起動し、入力したデータがWebサービスに送信されます。

9.6.4 Webページからのサービス起動時の処理内容

コンポーネントをJSFページにドロップして自動コンポーネント・バインディングの使用を選択すると、JDeveloperでは次の処理が実行されます。

  • JDeveloperでバッキングBeanを作成する場合は、JSPと同じ名前を使用してJavaBeanが作成され、view.backingパッケージに配置されます。

  • バッキングBeanに対するfaces-config.xmlファイルに、マネージドBeanが作成されます。 デフォルトでは、マネージドBean名はbacking_<page_name>で、このBeanでは、requestスコープが使用されます。

  • 新規に作成したBeanまたは選択したBeanでは、JSPに配置した各コンポーネント・タグに対するプロパティおよびアクセッサ・メソッドが追加されます。

  • EL式をバインディング属性の値として使用して、コンポーネント・タグがそのプロパティにバインドされます。

例9-13に、2つの入力コンポーネント(名前用と名字用)を追加したときにバッキングBeanに作成されるコードを示します。

例9-13 バッキングBeanの登録

public class Register {

    private HtmlHtml html1;
    private HtmlHead head1;
    private HtmlBody body1;
    private HtmlForm form1;
    private CoreInputText fname;
    private CoreInputText lname;

    public void setHtml1(HtmlHtml html1) {
        this.html1 = html1;
    }

    public HtmlHtml getHtml1() {
        return html1;
    }

    public void setHead1(HtmlHead head1) {
        this.head1 = head1;
    }

    public HtmlHead getHead1() {
        return head1;
    }

    public void setBody1(HtmlBody body1) {
        this.body1 = body1;
    }

    public HtmlBody getBody1() {
        return body1;
    }

    public void setForm1(HtmlForm form1) {
        this.form1 = form1;
    }

    public HtmlForm getForm1() {
        return form1;
    }

    public void setFname(CoreInputText inputText1) {
        this.fname = inputText1;
    }

    public CoreInputText getFname() {
        return fname;
    }

    public void setLname(CoreInputText inputText1) {
        this.lname = inputText1;
    }

    public CoreInputText getLname() {
        return lname;
    }
}

例9-14に、コンポーネントをRegisterバッキングBeanプロパティにバインドする、JSFページのコードを示します。

例9-14 自動コンポーネント・バインディングを使用するJSFコード

<afh:body binding="#{backing_Register.body1}" id="body1">
  <h:form binding="#{backing_Register.form1}" id="form1">
    <af:inputText label="First Name" binding="#{backing_Register.fname}"
                     id="fname"/>
    <af:inputText label="Label 2" binding="#{backing_Register.lname}"
                     id="lname"/>
  </h:form>
</afh:body>

コマンド・ボタンでは、メソッドへのバインドにAction属性またはActionListener属性を使用できます。 ここでは、action属性が提供するナビゲーション機能が不要であるため、action属性のかわりにactionListener属性が使用され、ユーザーは登録ページから移動しません。 コマンド・コンポーネントをバッキングBeanのメソッドにバインドすると、そのメソッドはユーザーがボタンをクリックすると起動します。

Webサービスを起動するメソッドを作成すると、プロキシの作成時に自動的に生成されたクライアント・クラスを使用してWebサービスを起動できます。 最初にサービスをコールし、次に、そのサービスに必要な操作をコールします。

たとえば、例9-15に示すように、Register.javaバッキングBeanのregister_actionメソッドは、最初にクライアント・クラスを使用してWebサービスをコールします。

例9-15 クライアント・クラスを使用したCustomerService Webサービスのコール

oracle.soademo.view.services.CustomerServiceClient myPort = new
                      oracle.soademo.view.services.CustomerServiceClient();

次に、メソッドは、例9-16に示すように、各コンポーネントの値を取得し、その値をStringに変換し、その内容をCustomerオブジェクトの対応するプロパティの値として設定することによって、顧客を作成します。

例9-16 顧客の作成

Customer newCust = new Customer();. . .
     newCust.setFname(fname.getValue().toString());
     newCust.setLname(lname.getValue().toString());
. . .

顧客が作成された後、メソッドは、例9-17に示すように、WebサービスのaddNewCustomer操作をコールして、作成した顧客に渡します。

例9-17 Webサービスでの操作のコール

myPort.addNewCustomer(newCust)