トップページ -> 実践知識 -> JavaServer Faces による Web アプリケーションとデータベースの連携 -> Java サーブレットでのデータベースプログラミング(JSF を使用)
[サイトマップへ]  

Java サーブレットでのデータベースプログラミング(JSF を使用)

サイト構成 連絡先,業績 実践知識 コンピュータ 教材 サポートページ

この Web ページでは, JavaServer Faces (JSF) を使って,リレーショナルデータベースと連携する簡単なWeb アプリケーション・プログラムを開発する手順を, 見本となるプログラムと図解で説明する.

見本となるプログラムは, ユーザ名とメールアドレスと登録種別をデータベースに登録するとともに, 固有のユーザIDを自動で割り当てる,というものです.


動作画面の例

この Web ページに書いたプログラムは,PostgreSQLで 動きます.ごく簡単な設定の変更で、MySQLDB2 Express-C,や Java DBHiRDB など, 他のリレーショナルデータベースソフトウエアでも動きます (変更は簡単です)。

【補足説明】

下記の 2つのサーバは別物です. 2つを同時に動かすことはできません(ポートを奪い合うことができないので).一方を動かすときは,もう一方を止めることになる.

  1. Eclipse 内部の tomcat サーバ:

    Eclipse では,Eclipse 内部の tomcat サーバが動き, Java サーブレットの動作テストなどに使う.

  2. 公開 tomcat サーバ:

    Eclipse とは無関係の tomcat サーバ(C:\tomcat55\bin\tomcat5w.exe 等で起動する Tomcat サーバのこと).当然, 公開 tomcat サーバが管理するディレクトリも Eclipse とは独立している.

なお,「Eclipse 内部の tomcat サーバ」を使えるようには, Eclipse で「新規サーバの定義」を行う必要があります.これは,1回行うだけで十分です.


JSF の概要

JSF を使ってプログラムを作成するときの作業項目は,次のようになっています.

  1. 入力フォーム
  2. アクション・コントローラ・メソッドの呼び出しと,画面遷移に関する記述
  3. ビジネスロジックの定義

    実際の処理を行うビジネスロジックは,上記で説明したフォーム・ビーン・オブ ジェクトや,アクション・コントローラ・メソッドを持つオブジェクト)とは分けるというのが一般の流儀です. つまり,アクション・コントローラ・メソッドが,ビジネスロジックを呼び出すことになる.

    ビジネスロジックのオブジェクトを自動生成する処理は,faces-config.xml に書きます.

上記のことを,実際のプログラム実行を通して理解しよう,というのがこの Web ページの目的です.


準備事項

必要となるソフトウエア

設定項目

前もって,Tomcat インストールディレクトリと, Spring 2 インストールディレクトリを調べておいてください.この Web ページでは,次のように書きます.

データベースシステムに関する項目

データベースシステムに関するいくつかの設定内容があります. この Web ページでは,設定内容を下記のように書きますので, 違う設定にする場合には, この Web ページの説明を読み替えてください.


テスト用データベースの作成

テスト用データベースとして,下記の SQL コマンドで,テーブル Account が作られていること.

CREATE TABLE Account (
    ユーザ名 VARCHAR(100) not null,
    メールアドレス VARCHAR(100) not null,
    登録種類 VARCHAR(20) not null,
    ユーザID INTEGER primary key not null );

※ SQL の実行は,Eclipse のデータツール・プラットホーム を使って,簡単にできます. データツール・プラットホームの使用法については, MySQLPostgreSQLJava DB (Derby) の場合に分けて,別の Web ページで説明している.


Eclipse の操作手順

以下,Eclipse を使います. 動的 Web プロジェクトの作成Apache MyFaces のインポートJava サーブレットの作成とテスト実行という一連の操作を,図解で説明する.

Eclipse の使用にあたって,事前に決めておく事項

Eclipse のプロジェクト等を作ります. この Web ページでは,Eclipse のプロジェクト名,Java パッケージ名は次のように記述します. (すでに同じ名前のプロジェクトがある,といったときは,プロジェクト名を変えてください).

ファイル構成

ファイル構成は次のようになる.

├MYFACES
 ├
 :
 ├Javaリソース; src
 │└hoge.hoge.com
 │ ├AccountDao.java
 │ ├AccountDso.java
 │ ├DataSourceFactory.java
 │ ├アクション.java
 │ ├システム内部状態.java
 │ ├登録ビジネスロジック.java
 │ └登録フォーム.java
 :
 ├WebContent ← Webアプリケーションのルート
  ├WEB-INF
  │ :
  │ ├faces-config.xml
  │ :
  │ ├web.xml
  │ :
  │ 
  ├failure.jsp
  ├index.jsp
  ├success.jsp
  └登録画面.jsp ← 入力フォームプログラム

動的 Web プロジェクトの新規作成

下記の手順で,動的 Web プロジェクトを新規に作成します.

  1. (もし,プロジェクト・エクスプローラが開いていなければ)プロジェクト・エクスプローラを開く

    「ウインドウ (Window)」→「ビューの表示 (Show View)」→「プロジェクト・エクスプローラ (Project Explorer)」 と操作します.

  2. プロジェクトの新規作成の開始

    ファイル」→「新規 (New)」→「プロジェクト (Project)
    または,プロジェクト・エクスプローラ内で,右クリック→「新規 (New)」→「プロジェクト (Project)」

  3. Web」の展開

    新規プロジェクトのウインドウが開くので, 「Web」を展開する.

  4. 動的 Webプロジェクト (Dynamic Web Project)」の選択

    展開した「Web」の下にある 「動的 Webプロジェクト (Dynamic Web Project)」を選び, 「次へ」をクリック.

  5. プロジェクト名の設定など

    設定用のウインドウが開くので,下記の設定を行う. 設定が終わったら,「次へ」をクリック.

  6. 次の「プロジェクト・ファセット」は,デフォルトのままでよい

    「次へ」をクリック.

    このウインドウが開かないことがあります.気にしなくてよい.

  7. 次の「Web モジュール」は,デフォルトのままでよい

    終了」をクリック.

  8. 作成されたプロジェクトの確認

    プロジェクト・エクスプローラで,いま作成した動的 Web プロジェクト MYFACES が表示されていることを確認する.

Apache MyFaces に関するファイル群 jsf-blank のインポート

Apache MyFaces の動作確認のため, 公開されている jsf-blank プログラム (jsf-blank-myfaces-with-extensions-app.zip) を実行してみます.

  1. JSF チュートリアルの Web ページを開く

    http://www.coreservlets.com/JSF-Tutorial/ をクリック.

  2. jsf-blank-myfaces-with-extensions-app.zip のダウンロード

    今開いている Web ページの「Section 1: Introducing JSF」のところにある jsf-blank-myfaces-with-extensions-app.zip をダウンロード.

  3. 解凍

    解凍してできたファイルのうち,WEB-INF/web.xml, WEB-INF/struts-config.xml, WEB-INF/lib, css/styles.css, index.jsp, welcome.jsp を使います (要するに全部を使います).

  4. Eclipse で,インポート開始

    プロジェクト・エクスプローラで, プロジェクト名 MYFACES の下の「WebContent」を右クリックし,「インポート」を選ぶ.

  5. インポート・ソースの選択

    一般」→「ファイルシステム」と操作した後, 「次へ」をクリック.

  6. ソース・ディレクトリの指定
    1. ソース・ディレクトリとして,先ほど解凍した jsf-blank-with-extensions を指定

    2. すると,ソース・ディレクトリの下に,ファイルの一覧が表示される. ここで,インポートすべきファイルを選ぶ. 「すべて選択」をクリック.

    3. 以上の操作の後,「終了」をクリック.

  7. 「上書きしますか?」に対しては「すべてはい」と答える

  8. インポートの結果,ファイルが増える

    WebContent\css, WebContent\WEB-ING\lib, WebContent\index.jsp, , WebContent\welcome.jsp が増えていることがみてとれる.web.xml などは上書きされる.

(オプション) 新しい版の MyFaces Core, MyFaces Tomahawk に入れ替え

さきほど作成したプロジェクト MYFACES の lib を展開すると, MyFaces Core と MyFaces Tomahawk のバージョンが分かります. 1.1.3 のように古いバージョンになっているでしょう. バージョンアップしたいときの手順は次の通りです.

  1. ファイルのダウンロード
    1. Apache MyFaces Project の ダウンロード用 Web ページを開く

      http://myfaces.apache.org/download.html

    2. MyFaces Core バージョン 1.1.6 バイナリ・リリースの選択

      Apache MyFaces Project の ダウンロード用 Web ページで,zip 形式ファイル myfaces-core-1.1.6-bin.zip をクリック. 

      ※ MyFaces Core 1.1 系列と,MyFacesTomahawk 1.1 系列を組み合わせて使うルールなので, MyFaces Core 1.2.4 をダウンロードしない.

    3. ミラーサイトの選択

      一番上の URL をクリック.

    4. ダウンロードしたファイルの解凍

      どこに解凍しても良いが,後で分かりやすいように C:\Program Files\Java の下に解凍しておく. 解凍の結果,新しいディレクトリ C:\Program Files\Java\myfaces-core-1.1.6 ができる.

    5. MyFaces Tomahawk バージョン 1.1.7 バイナリ・リリースの選択

      Apache MyFaces Project の ダウンロード用 Web ページで,zip 形式ファイル tomahawk-1.1.7-bin.zip をクリック.

    6. ミラーサイトの選択

      一番上の URL をクリック.

    7. ダウンロードしたファイルの解凍

      どこに解凍しても良いが,後で分かりやすいように C:\Program Files\Java の下に解凍しておく. 解凍の結果,新しいディレクトリ C:\Program Files\Java\tomahawk-1.1.7 ができる.

  2. MyFaces Core を,プロジェクトの WebContent\WEB-INF\lib にインポート

    先ほど作ったプロジェクト MYFACES に,MyFaces Core をインポートします.

    1. Eclipse で,インポートの開始

      プロジェクト・エクスプローラで,WebContent\Web-INF\lib右クリックし,「インポート」を選ぶ.

    2. インポート・ソースの選択

      一般」→「ファイルシステム」と操作した後, 「次へ」をクリック.

    3. MyFaces Core ファイルの指定
      1. ソース・ディレクトリとして,先ほど解凍した C:\Program Files\Java\myfaces-core-1.1.6\lib を指定

      2. すると,ソース・ディレクトリの下に,ファイルの一覧が表示される. ここで,インポートすべきファイルを選ぶ. 「lib」をチェック.

      3. 以上の操作の後,「終了」をクリック.

    4. 「上書きしますか?」に対しては「すべてはい」と答える

  3. MyFaces Tomahawk を,プロジェクトの WebContent\WEB-INF\lib にインポート

    上記と同様の手順で,MyFaces Tomahawk をインポートします.

    1. Eclipse で,インポートの開始

      プロジェクト・エクスプローラで,WebContent\Web-INF\lib右クリックし,「インポート」を選ぶ

    2. インポート・ソースの選択

      一般」→「ファイルシステム」と操作した後, 「次へ」をクリック.

    3. Tomahawk ファイルの指定
      1. ソース・ディレクトリとして,先ほど解凍した C:\Program Files\Java\tomahawk-1.1.7\lib を指定

      2. すると,ソース・ディレクトリの下に,ファイルの一覧が表示される. ここで,インポートすべきファイルを選ぶ. 「lib」をチェック.

      3. 以上の操作の後,「終了」をクリック.

  4. WebContent\WEB-INF\lib の古いファイルを削除

    次のファイルを削除する.削除するには, 「lib」を展開した後,削除したいファイルを右クリックして, 「削除」を選ぶ.

(Java DB (Derby) を使うときのみ) Apache Derby ネーチャーの追加と,サーバの開始

Java DB (Derby) を使うときに限り,プロジェクトへのApache Derby ネーチャーの追加 と,Java DB (Derby) サーバの開始を行います. これは, Java DB (Derby) を使うための追加的な設定です

  1. パッケージ・エクスプローラで,プロジェクト名 MYFACES を右クリック

  2. 「Apache Derby」→「Apache Derby ネーチャーの追加」

    「Apache Derby」が候補として現れないときは, Java DB (Derby) インストール の手順に従って,インストールと設定を行う.

  3. 「Apache Derby」→「Derby ネットワーク・サーバの開始」

    「Derby ネットワーク・サーバの開始」が選べない状態になっているときは, すでに開始済みなので,この手順は不要.

リレーショナルデータベース・ソフトウエアとして,Java DB (Derby) 以外を使う場合は,上記は不要です.

プロジェクトへの Spring プロジェクト・ネイチャーの追加

今度は,Spring JDBC を使うための設定です.

プロジェクトへの Spring プロジェクト・ネーチャーの追加を,次の操作で行います.

  1. プロジェクト・エクスプローラで,プロジェクト名 MYFACES を右クリック

  2. Spring ツール (Spring Tools)」→「Spring プロジェクト・ネーチャーの追加」と操作.

    Spring ツール (Spring Tools)」が候補として現れないときは, Eclipse の SpringIDE プラグイン の手順に従って,インストールを行う.

  3. プロジェクトの下に,「Spring Elements」が増えるので確認しておく.

    プロジェクト名 MYFACES の左横の 「+」をクリックして展開すると, 「Spring Elements」が増えている. (Spring プロジェクト・ネーチャーの追加ができたことが分かる).

WebContent\WEB-INF\lib への,jar ファイルのインポート

次の2種類の jar ファイルを,今度は,WebContent\WEB-INF\lib にインポートします. (先ほど,外部 jar ファイルとして追加したものと同じファイル).

プロジェクトの WebContent\WEB-INF\lib へのインポートを行う手順を下記に示す.

  1. プロジェクト構成物の表示

    プロジェクト・エクスプローラで, プロジェクト名 MYFACES の左横の「+」をクリックして展開すると,「Java リソース; src」などが現れる(その他,いろいろ,プロジェクトの構成物が現れる).

    ※ すでに展開済みのときは,この手順は不要.

  2. WebContent の展開

    WebContent の左横の「+」をクリックして展開する.

    ※ すでに展開済みのときは,この手順は不要.

  3. WEB-INF の展開

    WEB-INF の左横の「+」をクリックして展開する.

    ※ すでに展開済みのときは,この手順は不要.

  4. WEB-INF の下の lib を右クリックし,「インポート」を選ぶ.

  5. インポート・ソースの選択

    一般」→「ファイルシステム」と操作した後, 「次へ」をクリック.

  6. ファイルの指定

    インポートの手順は下記の通りである.

    1. 今出ているウインドウで,ソース・ディレクトリとして,各ファイルのディレクトリを指定.
    2. すると,ソース・ディレクトリの下に,ファイルの一覧が表示される. ここで,インポートすべきファイルを選ぶ. インポートすべきファイルをチェックする
    3. 以上の操作の後,「終了」をクリック.

    インポートするファイルが複数あるので, lib を右クリックし,「インポート」を選ぶという手順に戻って,やり直す必要があります. (つまり,ファイルの数だけ,インポートの操作を繰り返す). 上にも書きましたが,インポートすべきファイルは,次の2種類です.

  7. インポートの結果,ファイルが増える

    インポートの結果,ファイルが増えたことを確認したいときは,プロジェクト・エクスプローラで,「lib」を展開する.

Java パッケージ作成

Eclipse のプロジェクト・エクスプローラを使って, Java パッケージを作成します. Java パッケージ名には hoge.hoge.com のようなドメイン名を付ける習慣があることに注意してください. この Web ページでは,作成するJava パッケージ名は,hoge.hoge.com と書きます. (Java パッケージ名を変えるときは,読み替えてください).

  1. (もし,プロジェクト・エクスプローラが開いていなければ)プロジェクト・エクスプローラを開く

    「ウインドウ」→「ビューの表示」→「プロジェクト・エクスプローラ」 と操作します.

    Java パッケージの作成,クラスの作成などの作業は,プロジェクト・エクスプローラで行うことにします.

  2. Java パッケージを新規作成すべきプロジェクトの選択

    プロジェクト・エクスプローラに,プロジェクト一覧が表示されているはずです. Java パッケージを新規作成したいプロジェクト名 MYFACES右クリックして, 「新規」→「パッケージ」と操作します.

  3. Java パッケージ名の設定

    「Java パッケージ (Java package)」名前として,Java パッケージ名 hoge.hoge.comを記入する.

    その後,「終了」をクリック.

  4. Java パッケージの確認

    プロジェクト・エクスプローラにおいて, Java パッケージ hoge.hoge.com が増えていることを確認する.

    ※ プロジェクト・エクスプローラで, Java パッケージ名 hoge.hoge.comが表示されていないときは, プロジェクト MYFACES の左横の「+」をクリックして展開した後, 下の 「Java リソース; src」の左横の「+」をクリックして展開して下さい.


クラス定義と実行

  1. プロジェクト・エクスプローラで, プロジェクト名の下の 「Java リソース; src」または「src」の下を展開すると,パッケージ名 hoge.hoge.com が出ます.
  2. パッケージ名 hoge.hoge.com を右クリックして,クラス作成
  3. プロジェクト・エクスプローラで,クラスの「クラス名.java 」ダブルクリック すると,エディタが開きます.下記のプログラムを,カット&ペースト.

AccountDao.java

----------------------ここから----------------------
package hoge.hoge.com;

import java.sql.*;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;

// テーブル Person に関わる操作
public class AccountDao {
    // 使用するテーブル名
    final private static String TABLE = "Account";
    // private で SimpleJdbcTemplate オブジェクトを定義して,他のメソッドで使う,というのが決まり文句(詳しくは Spring のマニュアル)
    private SimpleJdbcTemplate jdbcTemplate;
   
    public void setDataSource(org.springframework.jdbc.datasource.DriverManagerDataSource dataSource) {
        this.jdbcTemplate = new SimpleJdbcTemplate(dataSource);
    }
    //
    // ステートメント実行の例 (テーブル定義)
    //
    public void initializeTable() {
        // executing statements;
        this.jdbcTemplate.update("drop table " + TABLE);
        // create table Account (ユーザ名 VARCHAR(100), メールアドレス VARCHAR(100), 登録種類 VARCHAR(20), ユーザID integer)
        this.jdbcTemplate.update("create table " + TABLE + " (ユーザ名 VARCHAR(100), メールアドレス VARCHAR(100), 登録種類 VARCHAR(20), ユーザID integer)");
    }

    //
    // 更新の例(1行挿入.値の更新)
    //
    public void insertTuple(AccountDso account) {
        this.jdbcTemplate.update("insert into " + TABLE + " values ( '" + account.getユーザ名() + "', '" + account.getメールアドレス() +
                                 "', '" + account.get登録種類() + "', " + account.getユーザID() + " )");
    }

    //
    // 問い合わせ
    //

    // タップル数
    public int getCount() {
        return this.jdbcTemplate.queryForInt("select count(*) from " + TABLE);
    }
    public int getMaxUserID() {
        return this.jdbcTemplate.queryForInt("select MAX(ユーザID) from " + TABLE);
    }

    // 結果が,AccountDso オブジェクトのリスト (つまり,結果が Java の PersonDso オブジェクトに格納されている)
    public List<AccountDso>getAllAccount() {   
        return this.jdbcTemplate.query(
                                       "select * from " + TABLE,
                                       new org.springframework.jdbc.core.simple.ParameterizedRowMapper<AccountDso>() {
                                           public AccountDso mapRow(ResultSet rs, int rowNum) throws SQLException {
                                               AccountDso p = new AccountDso();

                                               p.setユーザ名(rs.getString("ユーザ名"));
                                               p.setメールアドレス(rs.getString("メールアドレス"));
                                               p.set登録種類(rs.getString("登録種類"));
                                               p.setユーザID(rs.getInt("ユーザID"));

                                               return p;
                                           }
                                       }
                                       );       
    }

    // 選択条件あり.name で選択して,PersonDso オブジェクトを出力 (name が主キーならば PersonDso オブジェクトは1つ)
    public AccountDso selectNameById( String name ) {   
        return this.jdbcTemplate.queryForObject(
                                                "select * from " + TABLE + " where name = ?",
                                                new org.springframework.jdbc.core.simple.ParameterizedRowMapper<AccountDso>() {
                                                    public AccountDso mapRow(ResultSet rs, int rowNum) throws SQLException {
                                                        AccountDso p = new AccountDso();

                                                        p.setユーザ名(rs.getString("ユーザ名"));
                                                        p.setメールアドレス(rs.getString("メールアドレス"));
                                                        p.set登録種類(rs.getString("登録種類"));
                                                        p.setユーザID(rs.getInt("ユーザID"));

                                                        return p;
                                                    }
                                                },
                                                name );
    }
};
----------------------ここまで----------------------

AccountDso.java

----------------------ここから----------------------
package hoge.hoge.com;

//テーブル Account の1タップル(行)を格納するためのオブジェクト
public class AccountDso {
    private String ユーザ名 = null;
    private String メールアドレス = null;
    private String 登録種類 = null;
    private int ユーザID = 0;
   
	public String getユーザ名() {
		return ユーザ名;
	}
	public void setユーザ名(String ユーザ名) {
		this.ユーザ名 = ユーザ名;
	}
	public String getメールアドレス() {
		return メールアドレス;
	}
	public void setメールアドレス(String メールアドレス) {
		this.メールアドレス = メールアドレス;
	}
	public String get登録種類() {
		return 登録種類;
	}
	public void set登録種類(String 登録種類) {
		this.登録種類 = 登録種類;
	}
	public int getユーザID() {
		return ユーザID;
	}
	public void setユーザID(int ユーザid) {
		ユーザID = ユーザid;
	}
}
----------------------ここまで----------------------

DataSourceFactory.java

JDBC ドライバ名,データベース名などの定義を行うクラスです. DataSourceFactory.java は,PostgreSQL 用になっているので,他のリレーショ ナルデータベースシステムを使うときは,先頭部分を書き換えることを忘れないこと.

なお,インポートすべき JDBC ファイルの jar のファイル名は,参考のため,下記のプログラム DataSourceFactory.java に記載している.

Eclipse で DataSourceFactory クラスを新規作成したら,下記のプログラムをカット&ペースト.

JDBC プログラムで,データベースシステムと接続するとき, 新しいデータベースを作るには,「;create=true」を付ける.

----------------------ここから----------------------
package hoge.hoge.com;

import org.springframework.jdbc.datasource.DriverManagerDataSource;

public class DataSourceFactory {
        // 決まり文句 (ドライバクラス)
	final private static String PostgresJDBCDriver = "org.postgresql.Driver";
	final private static String MySQLJDBCDriver = "org.gjt.mm.mysql.Driver";
	final private static String JavaDBJDBCDriver = "org.apache.derby.jdbc.EmbeddedDriver";
	final private static String HiRDBDriver = "JP.co.Hitachi.soft.HiRDB.JDBC.PrdbDriver";

	// 下記の変数を正しく設定する
	// DBNAME, DBDIR, USER, PASS, JDBCDriver, DBURL


		// PostgreSQL 用デフォルト
		// Eclipse で PostgreSQL を使いたいときは,次の手順で,WebContent\WEB-INF\lib にインポートしておく.
		//     WebContent\WEB-INF\lib を右クリック.「一般」→「ファイルシステム」
		//     その後インポートすべきファイルとして,次のファイルを指定
		//       C:\Program Files\psqlJDBC\postgresql-8.3-603.jdbc4.jar
		final private static String DBNAME = "testdb"; // Database Name
		final private static String USER = "testuser"; // user name for DB.
		final private static String PASS = "hoge$#34hoge5"; // password for DB.
		final private static String JDBCDriver = PostgresJDBCDriver;
		final private static String DBURL = "jdbc:postgresql://localhost/" + DBNAME;


		// MySQL 用デフォルト
		// Eclipse で MySQL を使いたいときは,次の手順で,WebContent\WEB-INF\lib にインポートしておく.
		// http://dev.mysql.com/downloads/connector/ から,Connector/J をダウンロード
		// c:\Program Files\Java\mysql-connector-java-5.1.6\ に置く.
		//     WebContent\WEB-INF\lib を右クリック.「一般」→「ファイルシステム」
		//     その後インポートすべきファイルとして,次のファイルを指定
		//       c:\Program Files\Java\mysql-connector-java-5.1.6\mysql-connector-java-5.1.6-bin.jar を追加
		// final private static String DBNAME = "testdb"; // Database Name
		// final private static String USER = "testuser"; // user name for DB.
		// final private static String PASS = "hoge$#34hoge5"; // password for DB.
		// final private static String JDBCDriver = MySQLJDBCDriver;
		// final private static String DBURL = "jdbc:mysql://localhost/" + DBNAME;   

		// JavaDB用デフォルト
		// final private static String DBNAME = "dbdir;create=true"; // Java DB の場合は,Java DB データベースディレクトリ(相対)
		// final private static String DBDIR = "C:\\Program Files\\eclipse3.5\\eclipse\\"; // データベースが存在するディレクトリ
                // DTP, DBViewer などを使ってデータベースを生成した場合は Eclipse インストールディレクトリ
                // ij などを使ってデータベースを生成した場合は,c:\\<ワークスペース>\\<プロジェクト名>
		// final private static String USER = ""; // user name for DB. Java DB (Derby) の場合は空
		// final private static String PASS = ""; // password for DB. Java DB (Derby) の場合は空
		// final private static String JDBCDriver = JavaDBJDBCDriver;
		// final private static String DBURL = "jdbc:derby:" + DBDIR + DBNAME;

		// HiRDB用デフォルト
		// Eclipse で HiRDB を使いたいときは,次の手順で,WebContent\WEB-INF\lib にインポートしておく.
		//     WebContent\WEB-INF\lib を右クリック.「一般」→「ファイルシステム」
		//     その後インポートすべきファイルとして,次のファイルを指定
		//       C:\win32app\hitachi\hirdb_s\CLIENT\UTL\pdjdbc.jar
		// ユーザ名,パスワード: C:/windows/HiRDB.iniのPDUSERの値を調べておく
		// final private static String USER = "ユーザ名"; // user name for HiRDB. see C:/windows/HiRDB.ini
		// final private static String PASS = "パスワード"; // password for HiRDB. see C:/windows/HiRDB.ini
		// final private static String JDBCDriver = HiRDBDriver;
		// final private static String HiRDBServerName = "hitachi-664320D"; // HiRDB サーバのコンピュータ名
		// final private static String DBURL = "jdbc:hitachi:PrdbDrive://DBID=22200,DBHOST=" + HiRDBServerName + ",ENCODELANG=MS932"; // 'DBID=22200' is in "conf\pdsys";


        DriverManagerDataSource connect() {
                org.springframework.jdbc.datasource.DriverManagerDataSource dataSource = new DriverManagerDataSource();
                dataSource.setDriverClassName((String)JDBCDriver);
                dataSource.setUrl(DBURL);
                dataSource.setUsername(USER);
                dataSource.setPassword(PASS);
                return dataSource;
        }
}
----------------------ここまで----------------------

アクション.java

----------------------ここから----------------------
package hoge.hoge.com;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.jdbc.datasource.DriverManagerDataSource;

public class アクション {
	private 登録ビジネスロジック logic;
	private 登録フォーム regform;
	// 以下のうち,2つのセッターはJSFが呼び出す.
	// ※ JSFコンテナのほうで,登録ビジネスロジックと,登録フォームという
	//   2つのアプリケーションオブジェクトを保持する.
	public 登録ビジネスロジック getLogic() {
		return logic;
	}
	public void setLogic(登録ビジネスロジック logic) {
		this.logic = logic;
	}
	public 登録フォーム getRegform() {
		return regform;
	}
	public void setRegform(登録フォーム regform) {
		this.regform = regform;
	}
	
	// アクション・コントロール・メソッド
	public String doRegistration() {
		// JFS で HttpServletRequest, HttpSession を取得するときの決まり文句
		ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
		HttpServletRequest request = (HttpServletRequest)context.getRequest();
        HttpSession session = request.getSession();

        // セッション変数に入っていれば,ビジネスロジックにも設定済みなので,何もしない.
        システム内部状態 state = (システム内部状態)session.getAttribute("systemState");
        if ( state == null ) {
            state = new システム内部状態();
            state.reset();
            session.setAttribute("systemState", state);
            logic.setSystemState(state);
        }
       
        AccountDao accountDao = (AccountDao)session.getAttribute("accountDao");
        if ( accountDao == null ) {
            DataSourceFactory dataSourceFactory = new DataSourceFactory();
            DriverManagerDataSource dataSource = dataSourceFactory.connect();
            accountDao = new AccountDao();  
            accountDao.setDataSource(dataSource);

            session.setAttribute("accountDao", accountDao);
            logic.setAccountDao(accountDao);
        }
       
        //登録処理
        logic.registration(this.regform);
        // いつも成功
        return "success";
        // return "failure";
	}

}
----------------------ここから----------------------

システム内部状態.java

----------------------ここから----------------------
package hoge.hoge.com;

public class システム内部状態 {
    // システムの内部状態の保持.
    private int ユーザID = 0;
    private boolean 初期済か = false; // true ならば,ユーザIDに正しい値が入っているという意味
    private String 最終アクセスページID  = null;	// JSP 内の hiddenInput
    								// 「<h:inputHidden value="index" binding="#{regform.hiddenInput}"/>」でバインディング
    								// などで送られてくる「"index"」を入れる
	public int getユーザID() {
		return ユーザID;
	}
	public void setユーザID(int ユーザid) {
		ユーザID = ユーザid;
	}
    public boolean is初期済か() {
		return 初期済か;
	}
	public void set初期済か(boolean 初期済か) {
		this.初期済か = 初期済か;
	}
	public String get最終アクセスページID() {
		return 最終アクセスページID;
	}
	public void set最終アクセスページID(String 最終アクセスページid) {
		最終アクセスページID = 最終アクセスページid;
	}
	
    public void reset() {
        this.ユーザID = 0;
        this.初期済か = false;
        this.最終アクセスページID = null;
    }

}
----------------------ここまで----------------------

登録ビジネスロジック.java

package hoge.hoge.com;

import java.util.Date;

public class 登録ビジネスロジック
{
    // システムの内部状態の保持.
    private システム内部状態 state = null;
    public void setSystemState(システム内部状態 data) {
        this.state = data;
    }
    public システム内部状態 getSystemState() {
        return this.state;
    }
       
    // データアクセスオブジェクト (Dao) の保持.
    private AccountDao accountDao = null;
    public void setAccountDao(AccountDao DAO) {
        this.accountDao = DAO;
    }
    public AccountDao getAccountDao() {
        return this.accountDao;
    }
       
    private void createNewId(){
        System.out.println("ユーザID設定開始");
    	if ( !this.state.is初期済か() ) {
    	    System.out.println("ユーザID取得");	
        	// データベースが空の場合,ユーザIDを1にセットし,
        	// 空で無い場合,データベース内のユーザIDの最大値に1足した値にセットする
    		if ( this.accountDao.getCount() == 0 ) {
    			this.state.setユーザID(1);
    		}
    		else {
    			this.state.setユーザID( this.accountDao.getMaxUserID() + 1 );
    		}
    		this.state.set初期済か(true);
    	}
    	else {
    		// システム内部状態が初期済みなら,その「ユーザID」属性の値に1足すだけの処理
            int id = this.state.getユーザID();
            this.state.setユーザID( id + 1 );
    	}
    }
       
    /**
     * 登録ビジネスロジックの実装
     * 初期登録(Registration)の場合,DBにデータを登録
     * 登録フォームオブジェクトを与えて呼び出すこと.
     */
    public void registration( 登録フォーム regform ){
        // ユーザIDの生成
    	this.createNewId();
       
    	// システム内部状態の「最終アクセスページID」の更新
    	this.state.set最終アクセスページID(regform. getHiddenInput().getValue().toString());
    	
    	// タップル挿入
    	AccountDso a = new AccountDso();
        a.setユーザ名(regform.getユーザ名_必須());
        a.setメールアドレス(regform.getメールアドレス_必須());
        a.set登録種類(regform.get登録種類_必須());
        a.setユーザID(this.state.getユーザID());
        // this.accountDao.initializeTable();
        this.accountDao.insertTuple(a);
       
        // 確認表示
        System.out.println("--システム内部状態--");
        System.out.println("PAGEID:"+this.state.get最終アクセスページID());
       
        System.out.println("--DBに登録--");
        System.out.println("ユーザ名:"+a.getユーザ名());
        System.out.println("メールアドレス:"+a.getメールアドレス());
        System.out.println("登録種類:"+a.get登録種類());
        System.out.println("ユーザID:"+a.getユーザID());
        System.out.println("以上のデータでDBにINSERTしました");
               
        System.out.println("DATE:"+(new Date()));
    }
}
----------------------ここまで----------------------

登録フォーム.java

----------------------ここから----------------------
package hoge.hoge.com;
import java.util.List;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

// アクションフォーム・クラス
//   入力フォームデータの格納を行うとともに,アクション・コントロール・メソッドも持つ
public class 登録フォーム {

    private String ユーザ名_必須 = null;
    private String メールアドレス_必須 = null;
    private String 登録種類_必須 = null;
    // JSP 内の「<h:inputHidden value="index" binding="#{regform.hiddenInput}"/>」でバインディング
    public javax.faces.component.html.HtmlInputHidden hiddenInput = null;

	public String getユーザ名_必須() {
		return ユーザ名_必須;
	}

	public void setユーザ名_必須(String ユーザ名_必須) {
		this.ユーザ名_必須 = ユーザ名_必須;
	}

	public String getメールアドレス_必須() {
		return メールアドレス_必須;
	}

	public void setメールアドレス_必須(String メールアドレス_必須) {
		this.メールアドレス_必須 = メールアドレス_必須;
	}

	public String get登録種類_必須() {
		return 登録種類_必須;
	}

	public void set登録種類_必須(String 登録種類_必須) {
		this.登録種類_必須 = 登録種類_必須;
	}

	public javax.faces.component.html.HtmlInputHidden getHiddenInput() {
		return hiddenInput;
	}

	public void setHiddenInput(
			javax.faces.component.html.HtmlInputHidden hiddenInput) {
		this.hiddenInput = hiddenInput;
	}
	
	public void reset(){
        this.ユーザ名_必須 = null;
        this.メールアドレス_必須 = null;
        this.登録種類_必須 = null;
    }

}
----------------------ここまで----------------------

JSPファイルの作成

4つのJSPファイル index.jsp, success.jsp, failure.jsp, 登録画面.jsp を作成します.

  1. プロジェクト・エクスプローラで, プロジェクト名 MYFACES の下の 「WebContent」を展開しておく
  2. WebContent を右クリックして,下記の4つの JSP ファイルを作成.
  3. プロジェクト・エクスプローラで,JSP ファイルダブルクリック すると,エディタが開きます.下記のプログラムを,カット&ペースト.

index.jsp

----------------------ここから----------------------
<%@ page contentType="text/html; charset=Windows-31J" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t" %>

<f:view>
	<html>
		<head>
			<!-- タイトルを適切に付ける-->
        	<title>
        	登録画面
        	</title>
		</head>
		
		<body>
			<h:form id="form1">
			<!-- inputHidden の value="ほにゃらら" の部分は,value="index" のように,ページIDを付ける -->
			<h:inputHidden value="index" binding="#{regform.hiddenInput}"/>

    			<H1>
      				<center>登録画面</center>
    			</H1>
    			    			
				<f:subview id="table">
	  			<!-- インクルードするJSPファイル名は,画面ごとに異なる.書き換えて下さい-->
	  			<%@ include file="登録画面.jsp"%>
				</f:subview>

			</h:form>
		</body>
	</html>
</f:view>
----------------------ここまで----------------------

登録画面.jsp

ラジオボタンは2段組にしている(tomahawk の機能)

----------------------ここから----------------------
<%@ page contentType="text/html; charset=Windows-31J" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t" %>

<center>
<!-- panelGrid は,複数の列があるような表 -->
<h:panelGrid columns="2">
	<h:outputLabel for="text1" value="ユーザ名" />
	<h:inputText id="text1" value="#{regform.ユーザ名_必須}"/>

	<h:outputLabel for="text2" value="メールアドレス" />
	<h:inputText id="text2" value="#{regform.メールアドレス_必須}"/>
	
	<!-- 入れ子表 (ラジオボタンを2列にしたいときは columns="2", 1列にしたいときは columns="1"-->
	<h:panelGrid columns="2">
		<h:outputLabel value="登録種類" />
		<!-- layout="spread" にしているので,ラジオボタンを作るが表示はされない(2カラム表示を可能にするための工夫) -->
		<t:selectOneRadio id="radio1" value="#{regform.登録種類_必須}" layout="spread" styleClass="selectOneRadio">
			<f:selectItem itemValue="学生" itemLabel="学生"/>
			<f:selectItem itemValue="登録会員" itemLabel="登録会員"/>
			<f:selectItem itemValue="その他の会員" itemLabel="その他の会員"/>
			<f:selectItem itemValue="非会員" itemLabel="非会員"/>
		</t:selectOneRadio>		
		<!-- 作ったラジオボタンの表示.for="???" 部分は一致させること.index は 0 から始まる -->
		<t:radio for="radio1" index="0" />
		<t:radio for="radio1" index="1" />
		<t:radio for="radio1" index="2" />
		<t:radio for="radio1" index="3" />	
	</h:panelGrid>
	
	<h:outputLabel value="" />
	<h:commandButton id="button1" value="登録" action="#{action.doRegistration}"/>

</h:panelGrid>
</center>
----------------------ここまで----------------------

success.jsp

----------------------ここから----------------------
<%@ page contentType="text/html; charset=Windows-31J" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t" %>

<f:view>
	<html>
		<head>
			<!-- タイトルを適切に付ける-->
        	<title>
        	登録成功
        	</title>
		</head>
		<body>
			<h:form id="form1">

    			<H1>
      				<center>登録成功</center>
    			</H1>
    			
				<p>
				ユーザ名:
				<h:outputText value="#{regform.ユーザ名_必須}" />
				</p>

				<p>
				メールアドレス:
				<h:outputText value="#{regform.メールアドレス_必須}" />
				</p>
				
				<p>
				登録種類:
				<h:outputText value="#{regform.登録種類_必須}" />
				</p>
								
				<p>
				登録に成功しました
				</p>

				<p>
				<h:commandButton value="初めに戻る" action="returnToStart"/>
				</p>
								
			</h:form>
		</body>
	</html>
</f:view>
----------------------ここまで----------------------

failure.jsp

----------------------ここから----------------------
<%@ page contentType="text/html; charset=Windows-31J" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t" %>


<f:view>
	<html>
		<head>
			<!-- タイトルを適切に付ける-->
        	<title>
        	登録失敗
        	</title>
		</head>
		
		<body>
			<h:form id="form1">

    			<H1>
      				<center>登録失敗</center>
    			</H1>
    			
				<p>
				ユーザ名:
				<h:outputText value="#{regform.ユーザ名_必須}" />
				</p>

				<p>
				メールアドレス:
				<h:outputText value="#{regform.メールアドレス_必須}" />
				</p>
				
				<p>
				登録種類:
				<h:outputText value="#{regform.登録種類_必須}" />
				</p>
					
				<p>
				登録に失敗しました
				</p>
				
			</h:form>
		</body>
	</html>
</f:view>
----------------------ここまで----------------------

設定ファイル web.xml と faces-config.xml

WEB-INF/lib/web.xml

WEB-INF/lib/web.xml を,以下の手順で書き換える.

  1. プロジェクト・エクスプローラで,WEB-INF/lib/web.xml をダブルクリック

  2. エディタが開くので「ソース」をクリック

  3. ファイルエディタに切り替わるので,編集する.

    web.xml は下記のようにする.これは,JSF を使うときの決まり文句なので,悩まないこと.

    編集が終わったらプロジェクト・エクスプローラで,web.xml右クリックして,「リフレッシュ」(または「更新)を選ぶ

    extensionFilter の部分は、Apahce MyFaces の tomahawk コンポーネントと、sandbox コンポーネントを使うときに必要になる。

    (特記事項) web.xml の書き方は、tomahawk のバージョンに依存する。 下記に書いた web.xml は、tomahawk のバージョン 1.1.6 で確認済み。

----------------------ここから----------------------
<?xml version="1.0" encoding="UTF-8"?>

<!--
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
-->

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    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">
  <display-name>MyFaces Application</display-name>

    <!-- Extensions Filter -->
  <filter>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
    <init-param>
        <param-name>maxFileSize</param-name>
        <param-value>20m</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <!-- servlet-name must match the name of your javax.faces.webapp.FacesServlet entry -->
    <servlet-name>Faces Servlet</servlet-name>
  </filter-mapping>
<!-- extension mapping for serving page-independent resources (javascript, stylesheets, images, etc.)  -->
<filter-mapping>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
</filter-mapping>
  <!-- servlet -->
  <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-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
  -->
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>

  <!-- The Usual Welcome File List -->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>
----------------------ここまで----------------------

WEB-INF/lib/faces-config.xml

faces-config.xml は、ビーン名とクラス名のマッピングを取るなどのためのファイル。 ここでの設定の要点は下記の通りです.このことを頭に入れて理解してください.

マネージド・ビーン (Managed Bean)

----------------------ここから----------------------
<?xml version="1.0" encoding="UTF-8"?>
<!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>
	<managed-bean>
		<managed-bean-name>regform</managed-bean-name>
		<managed-bean-class>hoge.hoge.com.登録フォーム</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
	</managed-bean>
		<managed-bean>
		<managed-bean-name>logic</managed-bean-name>
		<managed-bean-class>hoge.hoge.com.登録ビジネスロジック</managed-bean-class>
		<managed-bean-scope>application</managed-bean-scope>
	</managed-bean>	
	<managed-bean>
		<managed-bean-name>action</managed-bean-name>
		<managed-bean-class>hoge.hoge.com.アクション</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
    	<managed-property>
      		<property-name>logic</property-name>
      		<property-class>hoge.hoge.com.登録ビジネスロジック</property-class>
      		<value>#{logic}</value>
   		</managed-property>
   		<managed-property>
      		<property-name>regform</property-name>
      		<property-class>hoge.hoge.com.登録フォーム</property-class>
      		<value>#{regform}</value>
   </managed-property>		
	</managed-bean>	
	
<navigation-rule>
    <from-view-id>*</from-view-id>
    <navigation-case>
        <from-outcome>success</from-outcome>
        <to-view-id>/success.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-outcome>failure</from-outcome>
        <to-view-id>/failure.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-outcome>returnToStart</from-outcome>
        <to-view-id>/index.jsp</to-view-id>
    </navigation-case>
</navigation-rule>
</faces-config>
----------------------ここまで----------------------

テスト実行

以下の手順で,index.jsp を実行する.
  1. プロジェクト・エクスプローラーで,index.jsp」を右クリック

  2. 実行 (Run As)」→「サーバーで実行 (Run on Server)」と操作

  3. サーバの選択

    ウインドウが開くので, 「ローカルホストの Tomcat v5.5 サーバ」が選択されていることを確認の後,「終了」をクリック.

  4. Tomcat のサーバが起動(または,再起動)するので確認する

    コンソール・ビューの表示を確認する.

  5. 実行結果の確認

    Eclipse の 組み込み Web ブラウザ (Internal Web ブラウザ)が開き,そこに実行結果が出る.

うまく動作しないときの確認項目