Java MVCフレームワークでショッピング風サイトを作る(Controller 編)
Java MVCフレームワークでショッピング風サイトを作る(Controller 編)
Java MVCフレームワークでショッピング風サイトを作って見たのでメモ。 今回はラストのController 編。前回Model 編の続き。
環境
仕様・構成
-
「ログイン画面(index.jsp)」からあらかじめDBに保存しているユーザIDをパスワードを使ってログインする。
-
「商品一覧画面(itemList.jsp)」へ遷移するので、 商品一覧の中から購入数(あらかじめ決めた在庫数まで)を選択して、購入ボタンを選択。
-
すると、 「購入確認画面(confirm_result.jsp)」へ遷移し、 購入ボタンをまた選択する。
-
商品が購入され、「購入結果画面(result.jsp)」へ遷移し、
-
一覧へ戻るを選択して、「商品一覧画面(itemList.jsp)」へ戻ってくる(在庫数は再計算されている)
また、購入履歴を選択した場合は、 過去に何を買ったかを「購入履歴画面(history.jsp)」へ遷移する。
Controller(Servlet)ファイルの確認
今回使うServlet は4種類。
クラス名 | 説明 |
---|---|
LoginServlet.java | ログイン・ログアウトなどの処理を受け付け |
ShoppingServlet.java | 商品一覧・購入履歴などの処理を受け付け |
BuyItemServlet.java | 商品購入処理を受け付け |
ResultServlet.java | 商品購入結果処理を受け付け |
商品を買う場合のActivity図
商品を買う場合のActivity図は、以下のようになる。
LoginServlet が、ログイン画面からform(POST) でユーザIDとパスワードを受け取り、ログイン処理を行う。 ログインに成功した場合ShoppingServlet へforward する。
ログインに成功した場合、ShoppingServlet がDBからShoppingDaoを使って、商品一覧情報を取得して、商品一覧画面 へ遷移する。 また、購入履歴リンクが選択された場合は、GETパラメータで判断して、購入履歴画面へ遷移する。
商品一覧画面から「購入」ボタンが選択された場合はBuyItemServlet が受け付け、購入確認画面へ遷移する。
購入確認画面からさらに「購入する」ボタンを選択すると、ResultServletが受け付け、購入結果画面へ遷移する。
状態(画面)遷移図
状態遷移図で表すと以下のようになる。
Controller(Servlet)の作成
LoginServlet.java
LoginServlet が、ログイン画面からform(POST) でユーザIDとパスワードを受け取り、DBのuserテーブルからLoginDaoを使ってユーザ情報を取ってきて、 ログイン処理を行う。
ログインに失敗した場合、ログインエラー画面(loginFailed.jsp)へforwardする。
ログインに成功した場合、セッションにユーザ情報(login_user_bean
)とログイン状態(login_state
) を付加(setAttribute
) し、 ShoppingServlet へforward する。
ログアウトのリンクが選択された場合、 セッションに付加されていたユーザ情報(login_user_bean
)とログイン状態(login_state
) を削除する。
package login;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet(name = "LoginServlet", urlPatterns = {"/LoginServlet"})
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* コンストラクタ.
*/
public LoginServlet() {
super();
}
/**
* Handles the HTTP GET
method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String para = request.getParameter("submit");
HttpSession session = request.getSession();
if (para.equals("logout")) {
// ④ クリックされたボタンが「logout」の場合はログアウト処理(セッションの破棄)を実施
session.removeAttribute("login_state");
session.removeAttribute("login_user_bean");
response.sendRedirect("./");
}
}
/**
* Handles the HTTP POST
method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String btn = request.getParameter("submit");
HttpSession session = request.getSession();
RequestDispatcher rd;
if (btn.equals("ログイン")) {
// ③-1-1 ログイン画面で入力されたIDとパスワードを取得
String id = request.getParameter("id");
String pass = request.getParameter("pass");
// ③-1-2 ユーザ情報をモデルに格納するために指示
// ③-1-3 ログイン処理クラスをインスタンス化
LoginDB login = new LoginDB();
// ③-1-4 ID処理クラスに②-1-1で取得したIDを渡してユーザ情報をモデルに格納
LoginUserBean bean = login.getUserData(id, pass);
// ③-2 モデルの情報を判定
if (bean != null) {
// ③-2-1 モデルの情報が存在する場合はsetAttributeメソッドを使ってセッションに情報をセット
// モデル(ユーザ情報)
session.setAttribute("login_user_bean", bean);
// ログイン状態
session.setAttribute("login_state", "login");
// ③-2-2 つぎに表示させる画面(ビュー)を指定
rd = request.getRequestDispatcher("./ShoppingServlet");
} else {
// ③-3 モデルの情報が存在しない(IDに紐づくユーザ情報がない)場合
// ③-3-1 つぎに表示させる画面(ビュー)を指定
rd = request.getRequestDispatcher("./jsp/loginFailed.jsp");
}
rd.forward(request, response);
} else if (btn.equals("ログアウト")) {
// ④ クリックされたボタンが「logout」の場合はログアウト処理(セッションの破棄)を実施
session.removeAttribute("login_state");
session.removeAttribute("login_user_bean");
response.sendRedirect("./");
}
}
}
ShoppingServlet.java
doPost
では、 ログインに成功した場合、ShoppingServlet がDB からShoppingDao を使って、商品一覧情報を取得して、商品一覧画面(itemList.jsp) へforward する。
doGet
では、 購入履歴リンクが選択された場合は、GETパラメータ(ShoppingServlet?submit=history
)で判断して、購入履歴画面(history.jsp) へ遷移する。
package shopping;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import login.LoginUserBean;
@WebServlet(name = "ShoppingServlet", urlPatterns = {"/ShoppingServlet"})
public class ShoppingServlet extends HttpServlet {
/**
* Handles the HTTP GET
method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
HttpSession session = request.getSession();
RequestDispatcher rd;
/*
* 履歴を表示する処理
*/
if (session.getAttribute("login_state").equals("login")) {
String para = request.getParameter("submit");
if (para.equals("history")) {
Shopping shopping = new Shopping();
// session からユーザID を取得
String user_id = *1.getId();
// 購入履歴を取得
ArrayList<HistoryBean> history_beans = shopping.getHistory(user_id);
// リクエストスコープにセットして画面移動
request.setAttribute("history", history_beans);
rd = request.getRequestDispatcher("./jsp/history.jsp");
rd.forward(request, response);
}
}
}
/**
* Handles the HTTP POST
method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
// 商品一覧を取得
Shopping shopping = new Shopping();
ArrayList<ItemBean> item_list = shopping.getItem();
System.out.println("item_list" + item_list);
// 商品一覧をリクエストスコープの属性にセット
request.setAttribute("itemList", item_list);
// 商品一覧画面に移動
RequestDispatcher rd = request.getRequestDispatcher("./jsp/itemList.jsp");
rd.forward(request, response);
}
/**
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}
}
BuyItemServlet.java
商品一覧画面から「購入」ボタンが選択された場合は、 doGet()
では、商品IDと購入数をGETパラメータでBuyItemServlet が受け付け、 購入確認画面(purchase_confirm.jsp) へ遷移する。
今回、doPost()
は使ってない。
package shopping;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 商品購入ページ処理クラス.
*/
@WebServlet("/BuyItemServlet")
public class BuyItemServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* コンストラクタ.
*/
public BuyItemServlet() {
super();
}
/**
* GETメソッドで呼び出された場合の処理
*
* @param request
* @param response
* @throws javax.servlet.ServletException
* @throws java.io.IOException
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// GETメソッドのパラメータ名を取得
Enumeration<String> names = request.getParameterNames();
String name; // 現在のパラメータ名
String item_id = ""; // 商品ID
String purchased_num; // 購入数
// 購入ボタンがクリックされた場所を特定
// 今回のサンプルプログラムの場合、クリックされた購入ボタンの値(value)と、リストボックスの値が取得できる
// 購入ボタンをクリックした後のURLにパラメータが記載されています
while (names.hasMoreElements()) {
// 渡ってきたパラメータを順番に処理
// パラメータ名を取得
name = names.nextElement();
// 購入ボタンがクリックされている場合は「購入」のパラメータが取得できる
if ("購入".equals(request.getParameter(name))) {
// 購入ボタンに付属している値(value)が商品IDになる
item_id = name;
}
}
// ドロップダウンリストから購入数を取得
purchased_num = request.getParameter(item_id + "list");
// 商品情報を取得
Shopping shopping = new Shopping();
System.out.println("item_id: " + item_id);
ItemBean item_bean = shopping.getItem(item_id);
System.out.println("item_bean: " + item_bean);
// 商品一覧をリクエストスコープの属性にセット
request.setAttribute("item_bean", item_bean);
request.setAttribute("purchased_num", purchased_num);
// 購入確認画面に移動
RequestDispatcher rd = request.getRequestDispatcher("./jsp/purchase_confirm.jsp");
rd.forward(request, response);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
ResultServlet.java
購入確認画面からさらに「購入する」ボタンを選択すると、 doPost()
で、 購入確認画面(purchase_confirm.jsp)にセットしていた値hiddenパラメータ)を ResultServlet が受け付け、購入結果画面(result.jsp)へforward する。
ShoppingDao を使って、在庫(stock)テーブルにアクセスして、 購入数分引いて更新する。 また、ユーザIDを使って、購入履歴(history)テーブルを更新する。
今回は、doGet()
は使ってない。
package shopping;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import login.LoginUserBean;
@WebServlet(urlPatterns = {"/ResultServlet"})
public class ResultServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* Handles the HTTP GET
method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
/**
* Handles the HTTP POST
method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
// ログインid取得
String user_id = *2.getId();
// 購入確認画面(purchase_confirm.jsp)にセットしていた値を取得(hiddenパラメータ)
String item_id = request.getParameter("item_id");
int purchased_num = Integer.parseInt(request.getParameter("item_quantity"));
ShoppingDao dao = null;
try {
/*
* 商品ID と購入数を元にDBを更新
* 対象の商品在庫をマイナスにする
*/
dao = new ShoppingDao();
dao.updateItem(item_id, purchased_num);
dao.updateHistory(user_id, item_id, purchased_num);
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
if (dao != null) {
dao.close();
}
}
// 商品結果画面に移動
RequestDispatcher rd = request.getRequestDispatcher("./jsp/result.jsp");
rd.forward(request, response);
}
}
コード
参考リンク
-
Java入門 -ショッピング風サイトの作成①- 井野 雄貴 先生 - 無料動画学習|schoo(スクー)WEB-campus
-
Java入門 -ショッピング風サイトの作成②- 井野 雄貴 先生 - 無料動画学習|schoo(スクー)WEB-campus