![見出し画像](https://assets.st-note.com/production/uploads/images/153101606/rectangle_large_type_2_eed1a97782669201605736860cb9ac96.png?width=1200)
ハッシュログイン機能付き図書の貸出履歴検索システム-JavaEE8,PostgreSQL
JavaEE8(JSP・Servlet)の環境でWebアプリケーションの開発方法を学ぶ講座をシリーズで提供しています。今回は部品として作成されたDBを操作するクラスファイル(DataAccessObject)を活用する方法を学びます。チーム開発での役割分担を想定しています。
2024年9月よりECLIPSEのバージョンを最新版(Version: 2024-06 (4.32.0))に変更しました。
開発概要
JavaEE8アプリケーション・サーバ(Tomcat)とデータベース・サーバ(PostgreSQL)を利用して開発を行うということを前提に実装を進めていきます。開発ツールには統合開発環境のEclipseを用いることにします。
題材としてハッシュログイン処理付き図書の貸出履歴管理を行うWebアプリをMVCモデルで作成します。ハッシュ値に変換されたパスワードにより認証を行います。
JavaEE8環境ですので使用言語は当然Java(JSP・Servlet)となり、設計技法にはMVCモデルを使います。MVCモデルとはWebアプリケーションの構成をModel(業務ロジック)ーView(表示)ーController(制御)に分割して設計する技法です。3つのモデルに役割分担することで部品化が促され、ひいてはチーム開発に貢献します。
今回、データベースの抽出処理など業務ロジックを実現するBeanは作成しません。他のチームメンバーが作成したという想定で提供されたBeanを活用することにします。
実装していく過程でEclipseの利用方法が不明な場合は、別途メール等でお知らせください。この講座では、作成済みの仕様と設計書から「JavaEE8環境でのMVCモデルの実装の仕組みを学ぶ」ことを目的とします。
開発方針
Webアプリケーションの開発環境には図1のようにEclipse2024を用います。
![](https://assets.st-note.com/img/1725426598-QDytPVpIm6BT8fLlZwcdiWbG.png)
Spring等のフレームワークは使用しません。これは、MVCモデルにおけるhttpプロトコルの処理の実装を直に学んでいただきたいためです。
開発に必要な仕様と最小限の設計ドキュメントは提示します。この情報をもとに、まずは、自分で試行錯誤しながら実装してみてください。
DB設計
認証方式
ログイン処理はハッシュ値による認証を行います。ハッシュ値は、文字列からハッシュ値へ変換した場合、そのハッシュ値から元の文字列に戻すことはできないという特徴があります。
ユーザが決めたパスワードをハッシュ値にして事前にDBに保存し、再度ユーザがログインした時に入力されたパスワードからハッシュ値を計算した結果とDBに保存してあるハッシュ値とを比較し、認証します。パスワードをDBにそのまま保存するよりセキュリティが高まります。今回はこの仕組みを実装します。
ハッシュ関数にはSHA-256を使います。SHA-256では256bitのハッシュ値(64桁)が出力されます。様々な場面でよく使用されている関数であり、256bit以上が推奨とされています(MD-5やSHA-128は推奨されません)。
Java標準機能であるMessageDigestクラスを使用することでSHA-256のハッシュ値を生成することは可能ですが若干使い辛いため、今回は、外部ライブラリである「Apache Commons Codec」のDigestUtilsクラスでハッシュ値を求めます。
論理設計
図書の貸出履歴管理のERDモデルを示します。
![](https://assets.st-note.com/img/1725427075-V4B7Dr2EWdvRJ5piKwXQl98t.png?width=1200)
物理設計
接続するPostgreSQLサーバのDB名は「library」とします。
(DB構造,スキーマ)
CREATE TABLE T_利用者
(利用者電話番号 CHAR(12) NOT NULL,
氏名 VARCHAR(20) NOT NULL,
所属 VARCHAR(20),
PRIMARY KEY (利用者電話番号));
CREATE TABLE T_作者
(作者id SERIAL NOT NULL,
作者名 VARCHAR(20) NOT NULL,
PRIMARY KEY (作者id));
CREATE TABLE T_発行所
(発行所id SERIAL NOT NULL,
発行所名 VARCHAR(20) NOT NULL,
郵便番号 CHAR(8),
住所 VARCHAR(50),
電話番号 CHAR(12),
PRIMARY KEY (発行所id));
CREATE TABLE T_書籍
(ISBNコード CHAR(17) NOT NULL,
書名 VARCHAR(50) NOT NULL,
発行所id INT NOT NULL,
初版発効日 DATE,
金額 INT,
冊数 INT,
PRIMARY KEY (ISBNコード),
FOREIGN KEY (発行所id)
REFERENCES T_発行所 ON DELETE RESTRICT ON UPDATE RESTRICT);
CREATE TABLE T_共著
(ISBNコード CHAR(17) NOT NULL,
作者id INT NOT NULL,
共著区分 VARCHAR(10) NOT NULL,
PRIMARY KEY (ISBNコード,作者id),
FOREIGN KEY (ISBNコード) REFERENCES T_書籍 ON DELETE RESTRICT
ON UPDATE RESTRICT,
FOREIGN KEY (作者id) REFERENCES T_作者 ON DELETE RESTRICT
ON UPDATE RESTRICT);
CREATE TABLE T_貸出し履歴
(履歴番号 INT NOT NULL,
ISBNコード CHAR(17) NOT NULL,
利用者電話番号 CHAR(12) NOT NULL,
貸出日 DATE,
返却日 DATE,
貸出冊番 INT,
PRIMARY KEY (履歴番号),
FOREIGN KEY (ISBNコード) REFERENCES T_書籍 ON DELETE RESTRICT
ON UPDATE RESTRICT,
FOREIGN KEY (利用者電話番号) REFERENCES T_利用者
ON DELETE RESTRICT
ON UPDATE RESTRICT);
SQL-DDLとSQL-DMLを含んだテキストファイルを添付します。
A5:SQL Mk-2などのSQLクライアントソフトを使ってSQL文を流し込んでください。図書の貸出履歴管理のテーブル群が作成されサンプルデータが入力されます。
(SQL-DDL,SQL-DML)
念のために、作成したすべてのテーブルとビューの中身を確認しておいてください。すべてのinsertデータがDBに格納されているか、しっかりと確認してください!図3のようにV_利用者毎貸出し履歴の出力件数は21件あります。
![](https://assets.st-note.com/img/1725432074-FmK1oNthLpjZxPbUiXnO6lzG.png?width=1200)
外部設計
接続urlはhttp://localhost:8080/booklib/Libraryとします。よってEclipseの動的Webプロジェクトの名前はbooklibとなり、サーブレットのurlパターンはLibraryとなります。
Eclipseのメニューバーより
ファイル→新規→動的Webプロジェクト→「booklib」プロジェクトを作成する→図4の内容で設定する
![](https://assets.st-note.com/img/1725433057-EYWO8CVByP1xT7DsgbRuLSat.png?width=1200)
※作成済みであればこの処理は必要ありません
urlにアクセスすると図5のような、ログイン画面が表示されます。IDは電話番号(ハイフン付き)でパスワードも電話番号(ハイフンなし)となります。正しく認証が行われると図6のように電話番号をキーとした貸出書籍の検索が行われ結果の貸出履歴が表示されます。
![](https://assets.st-note.com/img/1725496412-jlbLuh4JeXrWDpzK8acgC3HP.png?width=1200)
![](https://assets.st-note.com/img/1725496371-BEjGb4RWvh2OnkaIHfS58QVg.png?width=1200)
内部設計
クラス連携図は図7のようになります。
![](https://assets.st-note.com/img/1729215216-iK48DIrc9SCnluZEYxU5N7jk.png?width=1200)
DBに接続して図書検索を行う業務ロジック(DataAccessObject)を実装したBeanは提供されます。使い方とクラス図は以下のようになります。
PostgresConnectionBean.classの使い方とクラス図
(使い方)
コンストラクタの引数でPostgreSQLサーバのIPとDB名を指定して接続コネクションを実体化します。ゲッターメソッドで接続connectionを取得します。
接続パラメータはデフォルトで以下のように指定されています。当然、PostgreSQL用ドライバの登録が必要です。
・private String driver = "org.postgresql.Driver";
・private String url = "jdbc:postgresql://引数1:5432/引数2";
・private String user = "postgres";
・private String password = "postgres";
(クラス図)
![](https://assets.st-note.com/img/1725600208-b4vl9FWXUKwdtsjDVT28SuNq.png?width=1200)
BookLibraryUserCheckBean.classの使い方とクラス図
(使い方)
Beanは引数なしのコンストラクタで実体化します。
セッターメソッドでPostgreSQLサーバの接続connectionを設定します。userCheck()メソッドを実行することでT_USERテーブルから電話番号(tel)をキーとしてパスワードが登録されているかどうか検索します。
パスワードが登録されていればpasswordフィールドに内容が設定されます。
利用側のクラスはゲッターメソッドでpasswordフィールドの内容を取得します。
![](https://assets.st-note.com/img/1725600485-peGMEr2LxWbniJQA3yfcYguz.png)
BookLibraryArrayListBean.classの使い方とクラス図
Beanは引数なしのコンストラクタで実体化します。
セッターメソッドでPostgreSQLサーバの接続connectionを設定します。
bookSearch()メソッドを実行することでV_利用者毎貸出し履歴テーブルから電話番号(tel)をキーとして貸出履歴を検索します。
検索結果はhtml形式でresultSetフィールドに整形表組されます。
利用側のクラスはゲッターメソッドでresultSetフィールドの内容を取得します。
![](https://assets.st-note.com/img/1727391317-ktSuQPm3JyBNVjq8ahAXvM9x.png)
実装準備
ハッシュ算出用ライブラリの登録
「Apache Commons Codec」のDigestUtilsクラスでハッシュ値を求めます。よってcommons-codec-1.15.jarファイルをパッケージエクスプローラ内のbooklibプロジェクトのsrc/main/webapp/WEB-INF/libフォルダにドラッグ&ドロップして登録します。
![](https://assets.st-note.com/img/1725439140-x42FKS5HAsV8ZOl6wEXmYknp.png)
パスワードのハッシュ値の算出
パスワードハッシュ化プログラムの作成
DBに保存するハッシュ化されたパスワードの値を求めるために、通常のクラスファイルでHash化プログラムを作成します。
Eclipseパッケージ・エクスプローラより
booklibプロジェクトを右クリック→新規→クラス
→以下の内容で作成する
・HashCreate.java
パッケージ:jp.ict.aso.appli
名前:HashCreate
ソースコード:
![](https://assets.st-note.com/img/1725439682-rj7CecwB8tdpkiJIXvaZWmfu.png?width=1200)
HashCreate.javaを実行します。
エディタ画面を右クリック → 実行 → Javaアプリケーション
→ 結果は左下コンソールに出力される
![](https://assets.st-note.com/img/1725440190-WQuOehgmsLcy2N5Jtw0Cp3Eb.png?width=1200)
※結果のハッシュ値はコンソールからマウスで選択コピーして、プログラム内にコメントとして書き込んでおいたほうが、あとあと便利です。
![](https://assets.st-note.com/img/1725440541-IlKFyuMHp5ZVBzcW384se7wb.png?width=1200)
パスワード認証用テーブルに格納
ログイン情報を管理するT_USERテーブルを作成します。パスワード格納領域はHash文字列の幅にします。処理の手順は以下のようになります。
・T_USERテーブルを作成(PASSWORDフィールドは64文字となる)
・ハッシュ値を登録(図14で保存したハッシュ値などからINSERT文を生成する)
A5:SQL Mk-2などのSQLクライアントソフトを使って以下のSQL文を流し込みます。
(SQL-DDL)
create table T_USER(
TEL varchar(20) not null,
PASSWORD varchar(64) not null,
primary key(TEL)
);
(SQL-DML)
insert into T_USER values('03-1234-5678',
'03f19e1dad737c9a2d228fc5fba499253e79816bf4b66f64e067845bb12efeaf');
insert into T_USER values('045-123-4567',
'42559d4ba2c7e909c94cf550bff167fbdb533d71ea4f50ed70a3208ddc5f0ec6');
insert into T_USER values('045-666-7777',
'01fe7daff5c7626fc27eae7f9da28e03edb90aa4751063d9f482fea86f2b2c33');
念のために、作成したテーブルの中身を確認しておいてください。Webページからのコピペの流し込みでは不適切な文字が挿入される場合がありますので注意してください。図15のようにすべてのinsertデータがDBに格納されているか、しっかりと確認してください!
![](https://assets.st-note.com/img/1725495512-38o7UWEKxHRA1ZYutLGInrlV.png?width=1200)
PostgreSQLのjdbcドライバを配置
org.postgresql.driver.jarファイルをパッケージエクスプローラ内のbooklibプロジェクトのsrc/main/webapp/WEB-INF/libフォルダにドラッグ&ドロップして登録します。
![](https://assets.st-note.com/img/1725497417-W9XZci4v53tK1DVmJzBagEyT.png)
DAO用JavaBeansクラスの使用準備
(1)クラスファイルの準備をします
以下Windows環境を想定しています。
事前に「提供BeanLibrary」フォルダを作成しておきます。
(例 c:¥提供BeanLibrary)
提供BeanLibraryフォルダ内に以下の3つのクラスファイルを保存しておきます。
(PostgresConnectionBean.clas、BookLibraryUserCheckBean.class、BookLibraryArrayListBean.class)
その際パッケージの階層に従ってください。
(例 c:¥提供BeanLibrary¥jp¥ict¥aso¥model¥〇〇〇.class)
(2)DAO用の3つのクラスファイルをEclipseのビルド・パスに追加します
Eclipseパッケージ・エクスプローラより
booklibプロジェクトを右クリック→ビルド・パス→ビルド・パスの構成→「ライブラリ」タブ→「クラスパス」クリック→外部クラス・フォルダーの追加→「提供BeanLibrary」を指定します→最後に「適用して閉じる」をクリック
※Eclipse2024の場合 → booklibプロジェクトを右クリック→プロパティ
→Javaのビルド・パスで設定します。
※図17のように一度設定されていれば再度設定する必要はありません。
![](https://assets.st-note.com/img/1725505389-Un6EB3K0hIWTv95s7VwakotJ.png?width=1200)
実装手順
1.リクエストコントロール用Servletクラスを作成します
Eclipseパッケージ・エクスプローラより
booklibプロジェクトを右クリック→新規→その他→Web→サーブレット
→以下の内容で作成する
・BookLibraryServlet.java
パッケージ:jp.ict.aso.controller
クラス名:BookLibraryServlet
ソースコード:考えましょう! ※アノテーションは/Library
【ヒント】ソースコードの構成
doGet
// セッションを実体化してエラーメッセージ(なし)を設定
String message="";
HttpSession session=request.getSession();
session.setAttribute("error", message);
// bookLibraryLogin.jspにフォワード
doPost
// リクエストスコープの取得
request.setCharacterEncoding("UTF-8");
String tel = request.getParameter("tel");
String pass = request.getParameter("password");
// 入力されたパスワードのハッシュ値を求める
String hashPass = DigestUtils.sha256Hex(pass);
// DB接続パラメータの設定
String ip="192.168.56.200"; ← 自分のIPに変更
String db="library";
// DB接続用コネクション作成
PostgresConnectionBean pcb = new PostgresConnectionBean(ip,db);
Connection con=pcb.getConnection();
// ユーザチェックBeanの実体化(DB接続)
BookLibraryUserCheckBean blu = new BookLibraryUserCheckBean();
blu.setConnection(con);
blu.setTel(tel);
blu.userCheck();
// ユーザ(パスワード)チェックOK
if(hashPass.equals(blu.getPassword())) {
// DB検索(電話番号)
BookLibraryArrayListBean bla = new BookLibraryArrayListBean();
bla.setConnection(con);
bla.setTel(tel);
bla.bookSearch();
// DB接続用コネクション開放
pcb.releaseConnection(con);
// リクエストスコープに検索結果を保存
request.setAttribute("resultset", bla);
// bookLibraryResult.jspにフォワードして検索結果出力
// ユーザ(パスワード)チェックNG
}else {
// DB接続用コネクション開放
pcb.releaseConnection(con);
// エラーメッセージをセッションに設定
String message="電話番号またはパスワードが違います";
HttpSession session=request.getSession();
session.setAttribute("error", message);
// bookLibraryLogin.jspにフォワードしてアカウント再入力
}
2.ログイン画面のJSPファイルを作成します
Eclipseパッケージ・エクスプローラより
booklibプロジェクトを右クリック→新規→その他→Web→JSPファイル
→以下の内容で作成する
・bookLibraryLogin.jsp
保存場所:booklib/src/main/webapp/WEB-INF/jsp ← 注意!
ファイル名:bookLibraryLogin.jsp
ソースコード:考えましょう!
【ヒント】ソースコードの構成
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ログイン</title>
</head>
<% String message=(String)session.getAttribute("error"); %>
<BODY>
<CENTER>
<P><FONT FACE="Verdana" SIZE=6><B>Login</B></FONT></P>
<HR WIDTH=300>
<FORM METHOD="POST" ACTION="Library">
<TABLE BORDER=0>
<TR>
<TD>利用者電話番号:</TD>
<TD><INPUT TYPE=TEXT NAME="tel" SIZE=20></TD>
</TR>
<TR>
<TD>パスワード:</TD>
<TD><INPUT TYPE=PASSWORD NAME="password" SIZE=20></TD>
</TR>
</TABLE>
<INPUT TYPE=SUBMIT VALUE=ログイン><INPUT TYPE=RESET VALUE=リセット>
</FORM>
<HR WIDTH=300>
<%=message %>
<% session.removeAttribute("error"); %>
</CENTER>
</BODY>
</html>
3.DB検索結果画面のJSPファイルを作成します
Eclipseパッケージ・エクスプローラより
booklibプロジェクトを右クリック→新規→その他→Web→JSPファイル
→以下の内容で作成する
・bookLibraryResult.jsp
保存場所:booklib/src/main/webapp/WEB-INF/jsp ← 注意!
ファイル名:bookLibraryResult.jsp
ソースコード:考えましょう!リクエストスコープで転送されたbeanの
インスタンスを取得するのを忘れないように!
【ヒント】ソースコードの構成
<!DOCTYPE html>
<html>
<head>
<title>図書検索</title>
</head>
<body>
<CENTER>
<P><FONT FACE='Verdana' SIZE=6><B>図書貸出し検索</B></FONT></P>
<%=bal.getResultset() %><br>
<HR WIDTH=300>
<P><A HREF="Library">ログイン画面へ</A></P>
<HR WIDTH=300>
</CENTER>
</body>
</html>
実行確認
サーブレットクラス(BookLibraryServlet.java)を実行します。しかし、、、
1.InternalServerErrorとなります
実行用Beanのデプロイ(配置)が必要です。この設定を行わないと図18のような実行時エラーになります。
Eclipseパッケージ・エクスプローラより
BookLibraryServlet.javaを右クリック→実行→サーバーで実行
→図18のようにエラーとなる
![](https://assets.st-note.com/img/1725509646-ahOFvEbu1wy2DtcLsGoSPH3V.png?width=1200)
2.実行用Beanを配置します
提供された3つのクラスファイルをEclipseの実行時のクラスパスに追加します。
Eclipseプロジェクト・エクスプローラより
(パッケージ・エクスプローラではありません!)
booklibプロジェクトを展開→buildを展開→classesを展開→jpを展開→ictを展開→asoを展開→modelがなければ作成
図19のようにmodelフォルダの位置へ提供された3つのクラスファイルをドラッグ&ドロップすることで実行時クラスパスにBeanが追加されます。
※Eclipseを終了させると、再度追加が必要な場合があります。
![](https://assets.st-note.com/img/1725509903-a7AYJdyNVzSupMbjg6mCWtZr.png)
3.再度実行します
Tomcatサーバを再起動したのち、再度サーブレットクラス(BookLibraryServlet.java)を実行します。
Eclipseパッケージ・エクスプローラより
BookLibraryServlet.javaを右クリック→実行→サーバーで実行
→図20、図21のように実行される
![](https://assets.st-note.com/img/1725510317-7NJE4MgpCG6DshSAHa8n5L3T.png?width=1200)
![](https://assets.st-note.com/img/1725510245-prwkC91qd2bst8FVvDR0JayI.png?width=1200)
ソースコード例と提供Bean
以下に各プログラムのソースコードの例(本文内では「考えましょう!」になっている部分)を示しますので、実装の参考にしてください。
また、提供用のBeanとして DataAccessObject 関連の3つのクラスを次のセクションに置きますので、ダウンロードして使用してください。
ここから先は
¥ 1,000
この記事が気に入ったらチップで応援してみませんか?