Java MVCフレームワークでショッピング風サイトを作る(View編)
Java MVCフレームワークでショッピング風サイトを作る(View編)
Java MVCフレームワークでショッピング風サイトを作って見たのでメモ。今回はViewについてのメモ。
環境
仕様・構成
-
「ログイン画面(index.jsp)」からあらかじめDBに保存しているユーザIDをパスワードを使ってログインする。
-
「商品一覧画面(itemList.jsp)」へ遷移するので、 商品一覧の中から購入数(あらかじめ決めた在庫数まで)を選択して、購入ボタンを選択。
-
すると、 「購入確認画面(confirm_result.jsp)」へ遷移し、 購入ボタンをまた選択する。
-
商品が購入され、「購入結果画面(result.jsp)」へ遷移し、
-
一覧へ戻るを選択して、「商品一覧画面(itemList.jsp)」へ戻ってくる(在庫数は再計算されている)
また、購入履歴を選択した場合は、 過去に何を買ったかを「購入履歴画面(history.jsp)」へ遷移する。
その他の構成
-
商品一覧の「数量」は在庫数と同期して表示。 例えば在庫が5 であれば、 購入画面では5 までしか選べないようになっている。 今回は、手入力だとチェック処理が必要になるので、プルダウン(selectタグ)を使う。
-
商品一覧の「購入」ボタンは、在庫がなくなると非表示になる。
-
買い物カゴ機能はなし。
-
エラー画面は、今回はログインエラーのみ
-
エラー画面は、今回はログインエラーのみ
画面(JSP)ファイルの確認
今回使うjspは、7種類。
ファイル名 | 画面名 | 役割 |
---|---|---|
loin.jsp | ログイン画面 | ショッピング風サイトのトップページ |
loinFailed.jsp | ログインエラー画面 | ログイン処理失敗時のページ |
itemList.jsp | 商品一覧画面 | 買い物対象商品の表示ページ |
purchase_confirm.jsp | 購入確認画面 | 購入前の確認ページ |
result.jsp | 購入結果画面 | 購入結果の表示ページ |
history.jsp | 購入履歴画面 | ユーザの購入履歴照会ぺージ |
header.jsp | ヘッダー画面 | 共通ページ |
状態(画面)遷移図
状態遷移図で表すと以下のようになる。
DBの準備
使うデータベースは4種類。
テーブル名(論理名) | テーブル名(物理名) | 説明 |
---|---|---|
ユーザ | user | ユーザIDとパスワードなどの管理 |
商品 | item | 商品ID, 商品名などの管理 |
在庫 | stock | 商品在庫数の管理 |
購入履歴 | history | ユーザ毎の購入履歴の管理 |
データベース・テーブルの作成
-
データベースの作成。
create database shopping_sample character set utf8;
-
ユーザ(user)テーブルの作成: ユーザID、パスワード、名前と年齢のカラムを持つ。
create table shopping_sample.user(id varchar(10) not null primary key, pass varchar(10), name varchar(20), age int) character set utf8;
-
商品(item)テーブルの作成: 商品ID、商品名と値段のカラムを持つ。
create table shopping_sample.item(item_id char(5) not null primary key, item_name varchar(50), price int not null) character set utf8;
-
在庫(stock) テーブルの作成:商品IDと在庫数のカラムを持つ。
create table shopping_sample.stock(item_id char(5) not null primary key, quantity int) character set utf8;
-
購入履歴(history)テーブルの作成:注文ID(購入した時に割り当てられるID), ユーザID、商品ID、購入数のカラムを持つ。
create table shopping_sample.history(order_id int(4) zerofill auto_increment primary key not null, id varchar(10) not null, item_id char(5) not null, quantity int not null) character set utf8;
テストデータの追加
-
ユーザ(user)テーブルへの追加例
insert into shopping_sample.user(id, name, pass, age) values ("web01", "Taro", "password", 20);
insert into shopping_sample.user(id, name, pass, age) values ("web02", "Jiro", "pass", 17);
insert into shopping_sample.user(id, name, pass, age) values ("web03", "Saburo", "password", 19);
select * from shopping_sample.user; +-------+----------+--------+------+ | id | pass | name | age | +-------+----------+--------+------+ | web01 | password | Taro | 20 | | web02 | pass | Jiro | 17 | | web03 | password | Saburo | 19 | +-------+----------+--------+------+
-
商品(item)テーブルへの追加例
insert into shopping_sample.item(item_id, item_name, price) values ("s0001", "鋼のSword", 120);
insert into shopping_sample.item(item_id, item_name, price) values ("s0002", "ボロのメイル", 80);
insert into shopping_sample.item(item_id, item_name, price) values ("s0003", "ボロのシューズ", 40);
select * from shopping_sample.item; +---------+-----------------------+-------+ | item_id | item_name | price | +---------+-----------------------+-------+ | s0001 | 鋼のSword | 120 | | s0002 | ボロのメイル | 80 | | s0003 | ボロのシューズ | 40 | +---------+-----------------------+-------+
-
在庫(stock)テーブルの追加例。
insert into shopping_sample.stock(item_id, quantity) values ("s0001", 10);
insert into shopping_sample.stock(item_id, quantity) values ("s0002", 10);
insert into shopping_sample.stock(item_id, quantity) values ("s0003", 10);
select * from shopping_sample.stock; +---------+----------+ | item_id | quantity | +---------+----------+ | s0001 | 10 | | s0002 | 10 | | s0003 | 10 | +---------+----------+
-
購入履歴(history)テーブルは、 購入したときに自動的に追加される。
View(jspファイル)の作成
ログイン画面(index.jsp)
form(POST) でユーザIDとパスワードをLoginServlet へ 送る。
LoginServlet でログイン処理を行い、 ログインが成功すれば、ShoppingServlet へforwardする。
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<jsp:useBean id="login_user_bean" scope="session" class="login.LoginUserBean" />
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ショッピング風サイト ログイン画面</title>
<link href="css/shopping.css" rel="stylesheet" type="text/css" />
</head>
<body>
<main class="login_pane">
<h1>ようこそショッピング風サイトへ!</h1>
<p>ログインIDとパスワードを入力して下さい</p>
<form action="./LoginServlet" method="post">
<table class="table_form">
<tbody>
<tr>
<%-- ログイン済みの場合はIDを表示 --%>
<th>ログインID</th>
<td><input type="text" name="id" value="<%=login_user_bean.getId()%>"/></td>
</tr>
<tr>
<th>パスワード</th>
<td><input type="password" name="pass"/></td>
</tr>
</tbody>
</table>
<div class="buttons">
<input class="common_button" type="submit" name="submit" value="ログイン"/>
<%-- ログイン済みの場合はログアウトボタンを表示 --%>
<% if ("login".equals(session.getAttribute("login_state"))) { %>
<input class="common_button" type="submit" name="submit" value="ログアウト"/>
<% }%>
</div>
</form>
</main>
</body>
</html>
ログインエラー画面(loginFailed.jsp)
LoginServlet の中のログイン処理に失敗した場合、 loginFailed.jsp へforward される。
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%-- ログインエラー画面 --%>
<!DOCTYPE html>
<html>
<head>
<title>ショッピング風サイト エラー画面</title>
<link href="css/shopping.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>ログインエラー</h1>
<p>入力されたユーザは存在しません...</p>
<form>
<a class="common_button" href="./LoginServlet?submit=logout">戻る</a>
</form>
</body>
</html>
ヘッダー画面(header.jsp)
ログイン画面(index.jsp)以外に追加している。 ログイン名の表示、購入履歴(history.jsp)へのリンク、ログアウトのリンクがある。
ログアウトは、LoginServlet へのGETパラメータ(?submit=logout
) で判断させている。
購入履歴も同様に、ShoppingServlet へのGETパラメータ (?submit=history
) で判断させている。
<%@ page language="java" contentType="text/html charset=UTF-8" %>
<jsp:useBean id="login_user_bean" scope="session" class="login.LoginUserBean"/>
<link href="css/shopping.css" rel="stylesheet" type="text/css" />
<%-- header --%>
<header>
<%-- ログイン済みの場合はID を表示 --%>
<p>
ようこそ「<jsp:getProperty name="login_user_bean" property="name" />」さん!
<%-- Getのクエリで購入履歴かログアウトか判断させる --%>
<a href="ShoppingServlet?submit=history">購入履歴</a>
<a href="LoginServlet?submit=logout">ログアウト</a>
</p>
</header>
商品一覧画面(itemList.jsp)
ログインが成功した場合、ShoppingServlet側で商品(item)テーブルにアクセスし、全商品のデータをrequest にsetAttribute し、このitemList.jsp へforward する。
itemList.jsp は、request に付加された商品情報をgetAttribute し、 表(tableタグ) で表示する。
各商品の購入ボタンを選択すると、 商品ID と購入数を BuyItemServlet へform でPOSTする。
共通ページの読み込みは、jsp:include
タグを使えばいい。
<jsp:include page="header.jsp"></jsp:include>
<%@ page import="java.util.ArrayList"%>
<%@ page import="shopping.ItemBean"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%-- 商品一覧画面 --%>
<!DOCTYPE html>
<html>
<head>
<title>ショッピング風サイト 商品一覧画面</title>
<link href="css/shopping.css" rel="stylesheet" type="text/css" />
</head>
<body>
<%-- TODO:2-1 jsp:includeでヘッダー画面を読み込む --%>
<jsp:include page="header.jsp"></jsp:include>
<main>
<h1>商品一覧</h1>
<%-- リクエストスコープからBeanクラスの配列を取得 --%>
<% ArrayList<ItemBean> itemList = (ArrayList<ItemBean>) request.getAttribute("itemList"); %>
<form action="./BuyItemServlet">
<table class="shopping_table">
<tbody>
<tr>
<th>商品ID</th>
<th>商品名</th>
<th>価格</th>
<th>在庫数</th>
<th>数量</th>
</tr>
<%-- Beanの要素数分(商品の種類分)テーブルを作成 --%>
<% for (ItemBean bean : itemList) {%>
<tr>
<%-- 商品ID --%>
<td><%= bean.getItemId()%></td>
<%-- 商品名 --%>
<td><%= bean.getItemName()%></td>
<%-- 価格 --%>
<td class="int"><%= bean.getPrice()%></td>
<%-- 数量(在庫) --%>
<td class="int"><%= bean.getQuantity()%></td>
<%-- TODO:2-2 在庫が0の場合はリストボックスと購入ボタンを表示しない処理を入れる --%>
<% if (bean.getQuantity() != 0) {%>
<td>
<select class="list" name="<%= bean.getItemId()%>list">
<% for (int i = 0; i <= bean.getQuantity(); i++) {%>
<option value="<%= i%>"><%= i%></option>
<% }%>
</select>
</td>
<td class="button">
<input class="common_button" type="submit" value="購入" name="<%= bean.getItemId()%>">
</td>
<% } else { %>
<td class="button">売り切れ!</td>
<% } %>
</tr>
<% }%>
</tbody>
</table>
<a class="common_button" href="./">戻る</a>
</form>
</main>
</body>
</html>
購入確認画面(purchase_confirm.jsp)
商品ID と購入数の情報を持っているBuyItemServlet から、 商品情報と購入数をrequest にsetAttribure してpurchase_confirm.jsp へforward される。
商品ID と購入数を<input type="hidden">
で、ResultServlet へform(POST)で送信する。
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<jsp:useBean id="item_bean" scope="request" class="shopping.ItemBean"/>
<%-- 購入確認画面 --%>
<!DOCTYPE html>
<html>
<head>
<title>ショッピング風サイト 購入確認画面</title>
<link href="css/shopping.css" rel="stylesheet" type="text/css" />
</head>
<body>
<jsp:include page="header.jsp"/>
<main>
<h1>購入確認</h1>
<p>次の商品を購入しますか?</p>
<form action="./ResultServlet" method="post">
<table class="shopping_table">
<tbody>
<tr>
<th>商品ID</th>
<th>商品名</th>
<th>価格</th>
<th>在庫数</th>
<th>購入数</th>
</tr>
<tr>
<%-- リクエストスコープから表示する値を取得 --%>
<td><jsp:getProperty name="item_bean" property="itemId" /></td>
<td><jsp:getProperty name="item_bean" property="itemName" /></td>
<td class="int"><jsp:getProperty name="item_bean" property="price" /></td>
<td class="int"><jsp:getProperty name="item_bean" property="quantity" /></td>
<td class="int"><%=request.getAttribute("purchased_num")%></td>
<td class="button">
<input class="common_button" type="submit" value="購入する">
<% //TODO:2-5 hiddenでパラメータをセットしておく %>
<%-- 購入処理を行うため、hidden(画面には表示されない情報)に商品IDと購入数を設定しておく --%>
<input type="hidden" name="item_id" value="<jsp:getProperty property="itemId" name="item_bean"/>">
<input type="hidden" name="item_quantity" value="<%= request.getAttribute("purchased_num")%>">
</td>
</tr>
</tbody>
</table>
</form>
<form action="./ShoppingServlet" method="post">
<input class="common_button" type="submit" value="一覧に戻る">
</form>
</main>
</body>
</html>
購入結果画面(result.jsp)
ResultServlet の中で、 購入数から在庫数を再計算して在庫(stock)テーブルをupdate する。 result.jsp へforward する。
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%-- 購入結果画面 --%>
<!DOCTYPE html>
<html>
<head>
<title>ショッピング風サイト 購入結果</title>
<link href="css/shopping.css" rel="stylesheet" type="text/css" />
</head>
<body>
<jsp:include page="header.jsp"/>
<h1>購入結果</h1>
<p>購入しました。<img src="img/Thankyou.jpg" width="100" height="100"/></p>
<form action="./ShoppingServlet" method="post">
<input class="common_button" type="submit" value="一覧に戻る">
</form>
</body>
</html>
購入履歴画面(history.jsp)
header.jsp
にある購入履歴リンクを選択すると、 ShoppingServlet?submit=history のGETパラメータで処理される。
ShoppingServlet では、以下のように処理され、history.jsp へ遷移される。
-
session に付加されているユーザ情報(モデルLoginUserBean) から ユーザIDを取得.
-
ユーザIDを使って、DB の購入履歴(history)テーブルにアクセスし、
-
そのユーザの購入履歴情報を取得。
<%@ page import="java.util.ArrayList"%>
<%@ page import="shopping.HistoryBean"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<jsp:useBean id="login_user_bean" scope="session" class="login.LoginUserBean"/>
<%-- 購入履歴画面 --%>
<!DOCTYPE html>
<html>
<head>
<title>ショッピング風サイト 購入履歴</title>
<link href="css/shopping.css" rel="stylesheet" type="text/css" />
</head>
<body>
<jsp:include page="header.jsp"/>
<h1><jsp:getProperty name="login_user_bean" property="name" />さんの購入履歴</h1>
<%-- ShoppingServletで付加したattribute: historyをリクエストスコープからBeanクラスのListを取得 --%>
<% ArrayList<HistoryBean> historyList = (ArrayList<HistoryBean>) request.getAttribute("history"); %>
<table class="table_list">
<tbody>
<tr>
<th>商品ID</th>
<th>商品名</th>
<th>購入数</th>
</tr>
<%-- リクエストスコープから表示する値を取得 --%>
<% for (HistoryBean bean : historyList) {%>
<tr>
<%-- 商品ID --%>
<td><%= bean.getItemId()%></td>
<%-- 商品名 --%>
<td><%= bean.getItemName()%></td>
<%-- 数量(在庫) --%>
<td class="int"><%= bean.getQuantity()%></td>
</tr>
<% }%>
</tbody>
</table>
<form action="./ShoppingServlet" method="post">
<input class="common_button" type="submit" value="一覧に戻る">
</form>
</body>
</html>
コード
参考リンク
-
Java入門 -ショッピング風サイトの作成①- 井野 雄貴 先生 - 無料動画学習|schoo(スクー)WEB-campus
-
Java入門 -ショッピング風サイトの作成②- 井野 雄貴 先生 - 無料動画学習|schoo(スクー)WEB-campus