japan.internet.comThe Internet & IT Network
RSS
  • ニュース
  • コラム
  • リサーチ
  • ヘッドライン
  • 特集
  • ブログ
  • プレスリリース
  • 専門チャンネル
  • イベント
  • ランキング
  • ニュースメール
2008年10月12日
文字サイズ文字サイズ小文字サイズ中文字サイズ大
デベロッパー コラム2007年10月30日 10:00
DevX
DevX japan.internet.com 編集部メールホームrss
米国 Jupitermedia が運営する、
企業向けアプリケーションの開発者向けの技術情報/サービスサイト。

Ajax4JSFを利用したデータ検証

海外海外internet.com発の記事

はじめに

 AJAX(Asynchronous JavaScript and XML)テクノロジは、Webアプリケーションのユーザーインターフェースの使い勝手と柔軟性を高め、使用する帯域幅を最小限に抑えることのできる技術です。AJAXはJavaScriptとドキュメントオブジェクトモデル(DOM)とXMLHttpRequestに基づいており、Webページをサーバに送信することなくブラウザとサーバとの間で動的にXMLを転送できるWebテクニックとして使われています。

 AJAXの「A」にあたる「非同期(Asynchronous)」という用語には、サーバ上でXMLHttpRequestを処理してブラウザクライアントに応答を返すまでの間も、Webページの処理が継続して行われるという意味が含まれています。AJAXは、オートコンプリート機能(1つのフィールドに入力が行われたときに、対応する既存の情報をフォームに自動的に読み込む機能)、動的フォーム検証、Webページ全体の再読み込みを必要としないページセクションやページ領域の定期的な更新など、さまざまな機能に応用されています。

 JSF(JavaServer Faces)テクノロジは、J2EE(Java 2 Platform Enterprise Edition)アプリケーションのフロントエンドであるユーザーインターフェース(UI)を開発するための一連のコンポーネントを提供します。Ajax4JSFというオープンソースフレームワークを使用すると、JavaScriptを必要とせずにJSFアプリケーションにAJAX機能を追加できます。

 Ajax4JSFのコンポーネントライブラリを使用すると、JSFページ全体でAJAX機能を利用できるようになります。Ajax4JSFは、アクションと値の変更リスナに加えて、JSFフレームワークのサーバ側検証および変換機能をサポートします。また、イメージやカスケーディングスタイルシート(CSS)などの静的および動的リソースの管理と、Faceletsフレームワークもサポートします。Ajax4JSFを使用するには、次のツールをインストールしておく必要があります。

  • JDK 1.4〜1.6
  • JSF 1.1または1.2
  • J2EEアプリケーションサーバ(WebSphere 5.1〜6、WebLogic 8.1〜9.0、Oracle OC4J 10.1.3など)
  • XMLHttpRequestをサポートするブラウザ(Internet Explorer 6以上、Netscape Navigator 6以上など)

 ページ上のイベントによってAJAX要求が起動すると、ページの指定領域がAJAX応答で更新されます。

 それでは、Ajax4JSFフレームワークについて詳しく見ていきましょう。「web.xml」ファイルにはJSF要求とAJAX要求を区別するAjaxフィルタが登録されています。JSF要求の場合は、JSFページ全体がJSFコンポーネントツリーと同期します。これに対してAJAX要求の場合は、AJAX応答で更新されるのは<a4j:region>で指定されるAJAX領域だけです。

 ブラウザからサーバにAJAX要求を送信するには、AJAXアクションコンポーネント(AjaxCommandButton、AjaxCommandLink、およびAjaxSupport)を使用します。

 Ajaxコンテナは、AJAX要求時にデコードされ、AJAX応答で更新されるJSFページ上の領域です。JavaScriptエンジンはクライアント側で実行され、AJAX要求に応じてJSFページのさまざまな領域を更新します。

 Ajax4JSFには、JSFでAJAX機能を実装するためのコンポーネントライブラリが用意されています。表1に、よく使用されるコンポーネントを示します。

Ajax4JSFコンポーネント
Ajax4JSFコンポーネント

動的検証の設定

 JSF UIコンポーネントとAjax4JSFフレームワークを利用して、ユーザーがデータを入力するときに動的検証を行うアプリケーションを作成します。このサンプルアプリケーションでは、フォームはカタログエントリを作成するインターフェースとして動作し、カタログエントリはデータベーステーブルに格納されます。各カタログエントリにはCatalog IDと呼ばれる一意なフィールドがあり、各レコードには、雑誌名、発行元、エディション、記事タイトル、および著者に対応するフィールドがあります。

 AJAX Webテクニックを使用すると、ID値が有効かどうかを動的に検証できます。AJAXを使用せずにこの類の検証を実行するには、フォーム全体をサーバに送信して、特定のIDが存在するかどうかを確認しなければなりません。特定のIDが既にデータベースにある場合、そのIDを新しいIDとして使用することはできないため、フォームを別のID値で再送信する必要があります。

 AJAXを使用すると、Catalog IDフィールドへの値の入力時に、ID値を動的に検証できます。今回のサンプルアプリケーションでは、カタログレコードをOracleデータベースに格納します。従って、このサンプルを自分で試す場合は、Oracle Database 10gをサンプルスキーマ付きでインストールし、ORCLという名前のデータベースインスタンスを作成しておいてください。次のSQLスクリプトを使ってデータベーステーブルを作成できます。

CREATE TABLE OE.Catalog(CatalogID VARCHAR(25) 
  PRIMARY KEY, Journal VARCHAR(25), Publisher VARCHAR(25), 
  Edition VARCHAR(25), Title Varchar(255), Author Varchar(25));

INSERT INTO OE.Catalog VALUES('catalog1', 'Oracle Magazine', 
  'Oracle Publishing', 'July-August 2006', 
  'Evolving Grid Management', 'David Baum');

INSERT INTO OE.Catalog VALUES('catalog2', 'Oracle Magazine', 
  'Oracle Publishing', 'July-August 2005',
  'Tuning Undo Tablespace', 'Kimberly Floss');

 JDeveloper 10.1.3.2をインストールすることもお勧めします。このバージョンはJSF 1.1をサポートしています。Ajax4JSFのバイナリディストリビューションZIPファイル(ajax4jsf-1.0.6-binary.zip)をダウンロードし、展開します。

 それでは、実際にJSFアプリケーションを作成し、Ajax4JSFフレームワークを使ってこのアプリケーションにAJAX機能を追加しましょう。このJSFアプリケーションは、カタログレコードの簡単な入力フォームから成ります。前に説明したように、フォームには一意のCatalog IDフィールドが必要であり、このフィールドに入力した値はサーバ上で動的に検証され、ID値の検証ステータスを示すメッセージが表示されます。まず、Applications Navigatorに追加される新しいアプリケーションとプロジェクトを作成します。

  1. [File]→[New]を選択して、[New Gallery]ダイアログでJDeveloperアプリケーションを作成します。
  2. [Categories]ペインの[General]ノードを選択し、[Items]ペインの[Application]を選択し、[OK]をクリックします。
  3. アプリケーション名を指定し、[OK]をクリックします。
  4. プロジェクト名を指定します。

 次に、JSFページを作成する必要があります。

  1. [File]→[New]を選択し、[Web Tier]→[JSF]を選択します。
  2. [JSF JSP]を選択し、[OK]をクリックします。
  3. Create JSF JSPウィザードの[Next]をクリックします。
  4. [Web Application]フレームの[J2EE 1.4]を選択し、[Next]をクリックします。
  5. ファイル名「input.jsp」を指定し、[Next]をクリックします。
  6. [Component Binding]フレームの[Automatically Expose UI Components in a New Managed Bean]を選択し、[Next]をクリックします。
  7. JSF Core 1.0ライブラリとJSF HTML 1.0ライブラリが既定で選択されているため、次のフレームの[Next]をクリックします。
  8. 既定の[HTML Options]を選択し、[Next]をクリックします。
  9. [Finish]をクリックします。

 この手順を完了すると、「input.jsp」ファイルがAjaxJSFプロジェクトに追加されます。

 次に、カタログエントリが問題なく作成された場合に表示する「catalog.jsp」という名前のJSF JSPページを追加します。また、エントリの作成時にエラーが生じた場合に表示する「error.jsp」という名前のJSF JSPページも作成します。どちらのページも、Create JSF JSPウィザードで既定のオプションを選択する必要があります。

 [Component Binding]フレームの[Do Not Automatically Expose UI Components in a Managed Bean]オプションを選択します。「lib/Ajax4jsf.jar」ファイルと「lib/oscache-2.3.2.jar」ファイルを、Ajax4JSFバイナリディストリビューションからプロジェクトに追加する必要もあります。図1は、Ajax4JSFプロジェクトのプロジェクトライブラリを示しています。

図1 プロジェクトライブラリ: Ajax4JSFプロジェクトのプロジェクトライブラリはAjax4JSFバイナリディストリビューションに含まれている
図1 プロジェクトライブラリ: Ajax4JSFプロジェクトのプロジェクトライブラリはAjax4JSFバイナリディストリビューションに含まれている

 JARファイル(「ajax4jsf.jar」および「oscache-2.3.2.jar」)を、Ajax4JSFバイナリディストリビューションの「lib」ディレクトリからAjaxJSFアプリケーションの「WEB-INF/lib」ディレクトリにコピーします。図2は、AjaxJSFアプリケーションのディレクトリ構造を示しています。

図2 ディレクトリ構造: Applications NavigatorにはAjaxJSFアプリケーションの階層ディレクトリ構造が表示される
図2 ディレクトリ構造: Applications NavigatorにはAjaxJSFアプリケーションの階層ディレクトリ構造が表示される

入力の準備

 次に、JSFコンポーネントを使って入力フォームを作成します。まず、JSF HTMLコンポーネントライブラリからPanel Gridコンポーネントを「input.jsp」ページに追加します。Create PanelGridウィザードの[Next]をクリックします。[Create empty panel grid]を選択し、[PanelGrid Options]フレームで列数として2を指定し、[Finish]をクリックします。パネルグリッドに追加されるコンポーネントが、2列に配置されます。

 コンポーネントパレットの[Output Label]および[Input Text]コンポーネントをパネルグリッドに追加します。同様に、さらに5つの[Output Label]および[Input Text]コンポーネントを追加し、フォームの送信に使用される[Command Button]コンポーネントを追加します。また、ID値が有効かどうかを示す検証メッセージを表示するための[Output Text]コンポーネントも追加します(図3を参照)。[Property Inspector]エリアで、出力ラベルコンポーネントとコマンドボタンコンポーネントの値も指定します。

図3 フォームの作成: JDeveloper IDEのコンポーネントパレットを使って、5つのOutput LabelとInput Textコンポーネント、Command Buttonコンポーネント、およびOutput Textコンポーネントをパネルグリッドに追加する
図3 フォームの作成: JDeveloper IDEのコンポーネントパレットを使って、5つのOutput LabelとInput Textコンポーネント、Command Buttonコンポーネント、およびOutput Textコンポーネントをパネルグリッドに追加する

 ここで、OracleデータベースとのJDBC接続を作成する必要があります。この接続を作成するには、[Connections]エリアの[Database]ノードを右クリックし、[New Database Connection]を選択します。Create Database Connectionウィザードが表示されたら、[Next]をクリックします。接続名を指定し、[Type]フレームで接続タイプとして[Oracle JDBC]を選択し、[Next]をクリックします。

 この例では、[Authentication]フレームでユーザー名とパスワードに「OE」を指定し、[Next]をクリックします。次に、[Connection]フレームで既定の接続設定を選択し、[Next]をクリックします。[Test]フレームの[Test Connection]をクリックし、[Finish]をクリックします。[Connections]エリアに接続が追加されます。

 Oracleデータソースの「web.xml」ファイルにresource-ref要素を追加し、ajax4jsfフィルタおよびフィルタマッピングも「web.xml」に追加します。リスナクラスも指定する必要があります。「web.xml」ファイルをリスト1に示します。

 場合によっては、JSFの「faces-config.xml」設定ファイルを変更します。カタログエントリが作成される場合の「catalog.jsp」ページへのナビゲート、および「error.jsp」ページへのナビゲートに関するナビゲーションルールを追加します。

<?xml version="1.0" encoding="windows-1252"?>
<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config xmlns="http://java.sun.com/JSF/Configuration">
  <managed-bean>
    <managed-bean-name>backing_input</managed-bean-name>
    <managed-bean-class>ajaxjsf.backing.Input</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <!--oracle-jdev-comment:managed-bean-jsp-link:1input.jsp-->
  </managed-bean>
  <navigation-rule>
    <from-view-id>/input.jsp</from-view-id>
      <navigation-case>
        <from-outcome>catalog</from-outcome>
        <to-view-id>/catalog.jsp</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>error</from-outcome>
        <to-view-id>/error.jsp</to-view-id>
      </navigation-case>
  </navigation-rule>
</faces-config>
リスト1 web.xml
<?xml version = '1.0' encoding = 'windows-1252'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation=
  "http://java.sun.com/xml/ns/j2ee 
  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
  version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee">
  <description>Empty web.xml file for Web Application
  </description>
    <context-param>
      <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
      <param-value>server</param-value>
    </context-param>
    <filter>
      <display-name>Ajax4jsf Filter</display-name>
      <filter-name>ajax4jsf</filter-name>
      <filter-class>org.ajax4jsf.Filter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>ajax4jsf</filter-name>
      <servlet-name>Faces Servlet</servlet-name>
      <dispatcher>REQUEST</dispatcher>
      <dispatcher>FORWARD</dispatcher>
      <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>
    <listener>
      <listener-class>com.sun.faces.config.ConfigureListener
      </listener-class>
    </listener>
    <servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>javax.faces.webapp.FacesServlet
      </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
      <session-timeout>35</session-timeout>
    </session-config>
    <mime-mapping>
      <extension>html</extension>
        <mime-type>text/html</mime-type>
    </mime-mapping>
    <mime-mapping>
      <extension>txt</extension>
        <mime-type>text/plain</mime-type>
    </mime-mapping>
    <resource-ref>
      <res-ref-name>jdbc/OracleDBConnectionDS</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
    </resource-ref>
</web-app>

要求の送信

 アプリケーションを試すには、Ajax4JSFフレームワークを使用するJSF JSPページ「input.jsp」からAJAX要求を送信します。まずCatalog IDフィールドに<a4j:support/>要素を追加します。event属性にはAJAX要求を開始するイベントを指定し、action属性にはAJAX要求の送信時に呼び出すinputText_action()バッキングBeanメソッドを指定します。また、reRender属性を使ってAJAX応答で更新されるコンポーネントを指定します。Catalog IDフィールドのh:inputText要素は次のようになります。

<h:inputText binding="#{backing_input.inputText1}"
  id="inputText1">
  <a4j:support event="onkeyup" action=
    "#{backing_input.inputText_action}"
    reRender=
    "inputText2,inputText3,inputText4,inputText5,inputText6,
    commandButton1,outputText1" />
</h:inputText>

 Ajax4JSFコンポーネントライブラリを使用するには、次のtaglibディレクティブをJSF JSPページ「input.jsp」に追加します(全体のコードについてはリスト2を参照)。

<%@ taglib uri="https://ajax4jsf.dev.java.net/ajax" 
  prefix="a4j"%>

 コマンドボタンのクリックによりフォームが送信されるときにカタログエントリを作成するには、コマンドボタンにaction属性を追加して、コマンドボタンがクリックされたときにcommandButton_action()メソッドを呼び出します。コマンドボタンの要素は次のとおりです。

<h:commandButton value="Submit"
  binding="#{backing_input.commandButton1}" action=
  "#{backing_input.commandButton_action}"
  id="commandButton1"/>

 「catalog.jsp」を変更して、カタログエントリが作成されたことを伝えるメッセージを出力し、「error.jsp」を変更して、データベースの更新時にエラーが発生したことを伝えるメッセージを出力します。

 Catalog IDフィールドに入力された値は、データベーステーブルCatalogが配置されているサーバ側で検証されます。ID値がデータベースに既に存在する場合は、「Catalog Id is not valid」というメッセージが入力フォームに表示されます。これは、番号が既に存在するため、そのID値は新しいID番号として「有効でない」ことを意味します。Catalog IDフィールドの値がデータベースに存在しない場合は、「Catalog Id is valid」という検証メッセージが入力フォームに表示されます。有効なID値を判断するビジネスロジックは、サーバ側で指定できます。

 Catalog IDフィールドに値が指定されると、inputText_action()メソッドが呼び出されます。Catalog IDフィールドの内容を変更するたびに、つまり、新しい文字を入力するたびに、AJAX要求が送信されます。JDeveloperで設定されるOracleデータソースを使って、inputText_action()メソッドでOracleデータベースとの接続を確立します。

InitialContext initialContext = new InitialContext();
 javax.sql.DataSource ds = 
 (javax.sql.DataSource)initialContext.lookup(
 "java:comp/env/jdbc/OracleDBConnectionDS");
 java.sql.Connection connection = ds.getConnection();

 SQL文でStatementオブジェクトを実行します。

Statement stmt = connection.createStatement(
  ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

 フォームに指定されたCatalog ID値を取得し、SQLクエリを作成してOracleデータベースで実行できます。

String catalogID = (String)inputText1.getValue();
  String query = "SELECT * from Catalog WHERE CATALOGID=" + "'" + 
  catalogID + "'";

 SQLクエリを実行し、結果セットを取得します。

rs = stmt.executeQuery(query);

 結果セットが空でない場合は、検証メッセージを「Catalog Id is not valid」に設定し、フィールド値を設定し、コマンドボタンを無効にします。

if (rs.next()) {
  inputText2.setValue(rs.getString(2));
  inputText3.setValue(rs.getString(3));
  inputText4.setValue(rs.getString(4));
  inputText5.setValue(rs.getString(5));
  inputText6.setValue(rs.getString(6));
  outputText1.setValue(new String("Catalog Id is not Valid"));

  commandButton1.setDisabled(true);

}

 結果セットが空の場合、つまり、入力フォームに指定されたID値がデータベースに存在しない場合は、検証メッセージを「Catalog Id is valid」に設定し、フィールド値を空のStringに設定し、[Submit]ボタンを有効にします。

else {
  inputText2.setValue(new String());
  inputText3.setValue(new String());
  inputText4.setValue(new String());
  inputText5.setValue(new String());
  inputText6.setValue(new String());
  outputText1.setValue(new String("Catalog Id is Valid"));

  commandButton1.setDisabled(false);
}

 ID値が有効な場合、つまり、フィールドの値がデータベースに存在しない場合は、フォームフィールド値を取得し、データベースとの接続を確立し、新しいカタログエントリを作成します。

リスト2 input.jsp
<%@ taglib uri="https://ajax4jsf.dev.java.net/ajax" prefix="a4j"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<f:view>
  <html>
    <head>
      <meta http-equiv="Content-Type" content="text/html; 
        charset=windows-1252"/>
      <title>input</title>
      <h3>Catalog Entry Form</h3>
    </head>
    <body><h:form binding="#{backing_input.form1}" id="form1">
      <h:panelGrid columns="2" binding=
        "#{backing_input.panelGrid1}" id="panelGrid1">
        <h:outputLabel value="Catalog ID"
          binding="#{backing_input.outputLabel1}"
          id="outputLabel1"/>
        <h:inputText binding="#{backing_input.inputText1}"
          id="inputText1">
          <a4j:support event="onkeyup" action=
            "#{backing_input.inputText_action}"
            reRender="inputText2,inputText3,inputText4,inputText5,
            inputText6,commandButton1,outputText1" />
        </h:inputText>
        <h:outputLabel value="Journal" binding=
          "#{backing_input.outputLabel2}" id="outputLabel2"/>
        <h:inputText binding="#{backing_input.inputText2}" 
          id="inputText2"/>
        <h:outputLabel value="Publisher"
          binding="#{backing_input.outputLabel3}"
          id="outputLabel3"/>
        <h:inputText binding="#{backing_input.inputText3}" 
          id="inputText3"/>
        <h:outputLabel value="Edition" binding=
          "#{backing_input.outputLabel4}"
          id="outputLabel4"/>
        <h:inputText binding="#{backing_input.inputText4}" 
          id="inputText4"/>
        <h:outputLabel value="Title" binding=
          "#{backing_input.outputLabel5}"
          id="outputLabel5"/>
        <h:inputText binding="#{backing_input.inputText5}" 
          id="inputText5"/>
        <h:outputLabel value="Author" binding=
          "#{backing_input.outputLabel6}"
          id="outputLabel6"/>
        <h:inputText binding="#{backing_input.inputText6}" 
          id="inputText6"/>
        <h:commandButton value="Submit"
          binding="#{backing_input.commandButton1}" action=
          "#{backing_input.commandButton_action}"
          id="commandButton1"/>
        <h:outputText  binding="#{backing_input.outputText1}"
          id="outputText1"/>
      </h:panelGrid>
    </h:form></body>
  </html>
</f:view>
<%-- oracle-jdev-comment:auto-binding-backing-bean-
  name:backing_input--%>

バッキングBeanクラス

 バッキングBeanクラス「Input.java」のコードを、リスト3に示します。

リスト3 Input.java
package ajaxjsf.backing;

import java.sql.*;

import javax.faces.component.html.HtmlCommandButton;
import javax.faces.component.html.HtmlForm;
import javax.faces.component.html.HtmlInputText;
import javax.faces.component.html.HtmlOutputLabel;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.component.html.HtmlPanelGrid;

import javax.naming.InitialContext;

public class Input {
  private HtmlForm form1;
  private HtmlPanelGrid panelGrid1;
  private HtmlOutputLabel outputLabel1;
  private HtmlInputText inputText1;
  private HtmlOutputLabel outputLabel2;
  private HtmlInputText inputText2;
  private HtmlOutputLabel outputLabel3;
  private HtmlInputText inputText3;
  private HtmlOutputLabel outputLabel4;
  private HtmlInputText inputText4;
  private HtmlOutputLabel outputLabel5;
  private HtmlInputText inputText5;
  private HtmlOutputLabel outputLabel6;
  private HtmlInputText inputText6;
  private HtmlCommandButton commandButton1;
  private HtmlOutputText outputText1;

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

  public HtmlForm getForm1() {
    return form1;
  }

  public void setPanelGrid1(HtmlPanelGrid panelGrid1) {
    this.panelGrid1 = panelGrid1;
  }

  public HtmlPanelGrid getPanelGrid1() {
    return panelGrid1;
  }

  public void setOutputLabel1(HtmlOutputLabel outputLabel1) {
    this.outputLabel1 = outputLabel1;
  }

  public HtmlOutputLabel getOutputLabel1() {
    return outputLabel1;
  }

  public void setInputText1(HtmlInputText inputText1) {
    this.inputText1 = inputText1;
  }

  public HtmlInputText getInputText1() {
    return inputText1;
  }

  public void setOutputLabel2(HtmlOutputLabel outputLabel2) {
    this.outputLabel2 = outputLabel2;
  }

  public HtmlOutputLabel getOutputLabel2() {
    return outputLabel2;
  }

  public void setInputText2(HtmlInputText inputText2) {
    this.inputText2 = inputText2;
  }

  public HtmlInputText getInputText2() {
    return inputText2;
  }

  public void setOutputLabel3(HtmlOutputLabel outputLabel3) {
    this.outputLabel3 = outputLabel3;
  }

  public HtmlOutputLabel getOutputLabel3() {
    return outputLabel3;
  }

  public void setInputText3(HtmlInputText inputText3) {
    this.inputText3 = inputText3;
  }

  public HtmlInputText getInputText3() {
    return inputText3;
  }

  public void setOutputLabel4(HtmlOutputLabel outputLabel4) {
    this.outputLabel4 = outputLabel4;
  }

  public HtmlOutputLabel getOutputLabel4() {
    return outputLabel4;
  }

  public void setInputText4(HtmlInputText inputText4) {
    this.inputText4 = inputText4;
  }

  public HtmlInputText getInputText4() {
    return inputText4;
  }

  public void setOutputLabel5(HtmlOutputLabel outputLabel5) {
    this.outputLabel5 = outputLabel5;
  }

  public HtmlOutputLabel getOutputLabel5() {
    return outputLabel5;
  }

  public void setInputText5(HtmlInputText inputText5) {
    this.inputText5 = inputText5;
  }

  public HtmlInputText getInputText5() {
    return inputText5;
  }

  public void setOutputLabel6(HtmlOutputLabel outputLabel6) {
    this.outputLabel6 = outputLabel6;
  }

  public HtmlOutputLabel getOutputLabel6() {
    return outputLabel6;
  }

  public void setInputText6(HtmlInputText inputText6) {
    this.inputText6 = inputText6;
  }

  public HtmlInputText getInputText6() {
    return inputText6;
  }

  public void setCommandButton1(
    HtmlCommandButton commandButton1) {
    this.commandButton1 = commandButton1;
  }

  public HtmlCommandButton getCommandButton1() {
    return commandButton1;
  }

  public void setOutputText1(HtmlOutputText outputText1) {
    this.outputText1 = outputText1;
  }

  public HtmlOutputText getOutputText1() {
    return outputText1;
  }

  public String inputText_action() {
    ResultSet rs = null;
      try {
        InitialContext initialContext = new InitialContext();
        javax.sql.DataSource ds = 
        (javax.sql.DataSource)initialContext.lookup(
        "java:comp/env/jdbc/OracleDBConnectionDS");
        java.sql.Connection connection = ds.getConnection();

          Statement stmt = connection.createStatement(
            ResultSet.TYPE_SCROLL_INSENSITIVE, 
            ResultSet.CONCUR_READ_ONLY);

            String catalogID = (String)inputText1.getValue();

            String query = "SELECT * from Catalog WHERE 
              CATALOGID=" + "'" + catalogID + "'";
            rs = stmt.executeQuery(query);
            if (rs.next()) {
              inputText2.setValue(rs.getString(2));
              inputText3.setValue(rs.getString(3));
              inputText4.setValue(rs.getString(4));
              inputText5.setValue(rs.getString(5));
              inputText6.setValue(rs.getString(6));
              outputText1.setValue(new String(
                "Catalog Id is not Valid"));

              commandButton1.setDisabled(true);

            } else {
              inputText2.setValue(new String());
              inputText3.setValue(new String());
              inputText4.setValue(new String());
              inputText5.setValue(new String());
              inputText6.setValue(new String());
              outputText1.setValue(new String(
                "Catalog Id is Valid"));

              commandButton1.setDisabled(false);
            }

      } catch (SQLException e) {
        System.out.println(e.getMessage());
      } catch (javax.naming.NamingException e) {
        System.out.println(e.getMessage());
    }
    return null;
  }

  public String commandButton_action() {
    try {
      //Obtain Connection
      InitialContext initialContext = new InitialContext();
      javax.sql.DataSource ds = 
        (javax.sql.DataSource)initialContext.lookup(
        "java:comp/env/jdbc/OracleDBConnectionDS");
        java.sql.Connection conn = ds.getConnection();

        String catalogId = (String)inputText1.getValue();
        String journal = (String)inputText2.getValue();
        String publisher = (String)inputText3.getValue();
        String edition = (String)inputText4.getValue();
        String title = (String)inputText5.getValue();
        String author = (String)inputText6.getValue();

        Statement stmt = conn.createStatement();
        String sql = 
          "INSERT INTO Catalog VALUES(
          " + "¥'" + catalogId + "¥'" + "," + "¥'" + journal + 
          "¥'" + "," + "¥'" + publisher + "¥'" + "," + "¥'" + 
          edition + "¥'" + "," + "¥'" + title + "¥'" + "," + 
          "¥'" + author + "¥'" + ")";

          stmt.execute(sql);

          stmt.close();
          conn.close();

    } catch (javax.naming.NamingException e) {
      return "error";
    } catch (SQLException e) {
      return "error";
    }

      return "catalog";

    }
}

応答の処理

 アプリケーションを実行して、フォームに指定されたID値を、Catalogデータベーステーブル内のデータに対して検証することができます。入力されたID値が既存の値の場合、アプリケーションはエントリを無効と判断し、その結果を伝えるメッセージを表示します。既存レコードのその他のフォームフィールド値も表示され、[Submit]ボタンが無効になります。

 入力されたID値がデータベーステーブルに存在しない場合、アプリケーションはエントリを有効と判断し、その結果を伝えるメッセージを表示します。他のフォームフィールドは空のString値に設定され、[Submit]ボタンが有効になります。

 有効なIDの場合は、カタログエントリを作成し、[Submit]ボタンを使ってそのエントリを格納できます。<a4j:support>タグのreRender属性で設定されるJSFコンポーネントは、AJAX応答で更新されるコンポーネントを指定します。

 「input.jsp」を右クリックし、[Run]を選択して、JSFページを実行します。Catalog IDフィールドに値を指定します。フィールドが変更されるたびに(文字が入力されるたびに)AJAX要求が送信され、ID番号が一意(有効)であることを示す検証メッセージが表示されます。

 次に、データベースに既に存在するID値、例えば「catalog2」を指定してみましょう。「Catalog Id is not valid」メッセージが表示されることに注目してください。値がデータベースに存在するため、オートコンプリート機能によってフォームフィールドに値が設定され、[Submit]ボタンが無効になります。

 これまでの説明でお分かりのように、Ajax4JSFコンポーネントライブラリによってJSFアプリケーションにAJAX機能を追加できます。AJAX機能を追加するためにJavaScriptコードをわざわざ作成する必要はありません。

著者紹介

Deepak Vohra(Deepak Vohra)
O'Reillyの技術レビュー担当者として『WebLogic: The Definitive Guide』を担当。NuBeanコンサルタント、Web開発者でもある。Sun認定資格(Java 1.4プログラマおよびWebコンポーネントディベロッパJ2EEバージョン)を取得。メールの宛先はdvohra09@yahoo.com。
海外のインターネットコムアメリカ韓国ドイツトルコ
Copyright 2008 Jupitermedia Corporation All Rights Reserved.http://www.internet.com/