金子邦彦研究室プログラミングJavaServer Faces による Web アプリケーションとデータベースの連携Java サーブレットでのデータベースプログラミング(JSF を使用)

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

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

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

[image]
動作画面の例

この Web ページに書いたプログラムは,PostgreSQL の利用で 動く.ごく簡単な設定の変更で、MySQL の利用Java DB 他のリレーショナルデータベースソフトウェアでも動く

【補足説明】

下記の 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 ページの目的です.

準備事項

前準備

JDK (Java Development Kit) のインストール

Eclipse のインストール

その他

設定項目

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

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

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

動的 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)」を選び, 「次へ」をクリック.

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

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

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

    「次へ」をクリック.

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

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

    終了」をクリック.

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

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

    [image]

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

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

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

    https://www.tutorialspoint.com/jsf/index.htm をクリック.

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

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

    [image]
  3. 解凍

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

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

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

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

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

    [image]
  6. ソース・ディレクトリの指定
    1. ソース・ディレクトリとして,先ほど解凍した jsf-blank-with-extensions を指定
    2. すると,ソース・ディレクトリの下に,ファイルの一覧が表示される. ここで,インポートすべきファイルを選ぶ. 「すべて選択」をクリック.
    3. 以上の操作の後,「終了」をクリック.

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

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

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

    [image]

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

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

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

      https://myfaces.apache.org/#/

    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 をダウンロードしない.

      [image]
    3. ミラーサイトの選択

      一番上の URL をクリック.

      [image]
    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 をクリック.

      [image]
    6. ミラーサイトの選択

      一番上の URL をクリック.

      [image]
    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右クリックし,「インポート」を選ぶ.

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

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

      [image]
    3. MyFaces Core ファイルの指定
      1. ソース・ディレクトリとして,先ほど解凍した C:\Program Files\Java\myfaces-core-1.1.6\lib を指定
      2. すると,ソース・ディレクトリの下に,ファイルの一覧が表示される. ここで,インポートすべきファイルを選ぶ. 「lib」をチェック.
      3. 以上の操作の後,「終了」をクリック.

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

      [image]
  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. 以上の操作の後,「終了」をクリック.

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

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

    [image]

(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 プロジェクト・ネーチャーの追加ができたことが分かる).

    [image]

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 のようなドメイン名を付ける習慣があることに注意してください. このページでは,作成するJava パッケージ名は,hoge.hoge.com と書く. (Java パッケージ名を変えるときは,読み替えてください).

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

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

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

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

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

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

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

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

    [image]
  4. Java パッケージの確認

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

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

    [image]

クラス定義と実行

  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 にインポートしておく.
        // https://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=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="https://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=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="https://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=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="https://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=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="https://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 をダブルクリック

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

    [image]
  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 サーバ」が選択されていることを確認の後,「終了」をクリック.

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

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

  5. 実行結果の確認

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

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