MVCに分けて行う開発の流れをシンプルな例を通して学習しよう。
お題
ホスト名/curryapp/CurryMain
上記のURLでブラウザからアクセスすると。以下のようなフォームが表示される

項目を入力し、送信ボタンを押す

以下のように出力される

この際、トッピングは以下の中からのランダムに重複なく選ばれる
"大根","セロリ","里芋","カブ","ゴーヤ","キュウリ","カツオのたたき","ラム肉",
"鯖の水煮","ブリ","タコ","ちくわ","魚肉ソーセージ","こんにゃく","ツナ缶",
"納豆","アボガド","レーズン","あげ玉",
戻るを押すと最初に戻る

作成
ファイル構成
model
model.Curry.java //javaBeansの仕様を満たしたクラス
model.CurryLogic.java //入力された情報をもとに合計などを計算しインスタンスを完成させるクラス
controller
controller.CurryMain.java //HttpServletクラスを継承して作成する(サーブレット)
view
/WEB-INF/view/form.jsp //フォームを表示する
/WEB-INF/view/result.jsp //結果を表示する
作成
model.Curry.java
結果画面を見て、何が必要なのかを考慮し以下のようなクラスを作成する。
package model;
import java.io.Serializable;
public class Curry implements Serializable{
private String base;
private String toppingNum;
private String toppingResult;
public Curry() {}
public Curry(String base,String toppingNum) {
this.base=base;
this.toppingNum=toppingNum;
}
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public String getToppingNum() {
return toppingNum;
}
public void setToppingNum(String toppingNum) {
this.toppingNum = toppingNum;
}
public String getToppingResult() {
return toppingResult;
}
public void setToppingResult(String toppingResult) {
this.toppingResult = toppingResult;
}
}
model.CurryLogic.java
package model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class CurryLogic {
private static final String[] TOPPINGS ={
"大根","セロリ","里芋","カブ","ゴーヤ","キュウリ","カツオのたたき","ラム肉",
"鯖の水煮","ブリ","タコ","ちくわ","魚肉ソーセージ","こんにゃく","ツナ缶",
"納豆","アボガド","レーズン","あげ玉",
};
public void execute(Curry curry) {
//トッピング数
int toppingCount = Math.min(TOPPINGS.length, Integer.parseInt(curry.getToppingNum()));
//配列を元にListを作成
List<String> list= new ArrayList<>(Arrays.asList(TOPPINGS));
//リストをシャッフル
Collections.shuffle(list);
String toppingResult="";
for(int i=0;i<toppingCount;i++) {
toppingResult+=list.get(i);
}
//以下のように1行で行なうこともできる
//toppingResult=String.join("",list.subList(0,toppingCount));
//トッピングをセット
curry.setToppingResult(toppingResult);
}
}
controller.CurryMain.java
処理の流れを考えながらまずはdoGetを作成する。form.jspへフォワードするだけの処理だ。(doPostはカラにしておく)
package controller;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/CurryMain")
public class CurryMain extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("WEB-INF/view/form.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
WEB-INF/view/form.jsp
WebContentの中にあるWEB-INFフォルダ内にviewフォルダを作成し、その中にform.jspファイルを作成する。内容は以下
フォームを表示するだけの処理だ。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>カレーメーカー</title>
</head>
<body>
<form action="/curryapp/CurryMain" method="post">
<p>ベースとなるカレーを選択</p>
<input type="radio" name="base" id="pork" value="ポーク" required><label for="pork">ポーク</label>
<input type="radio" name="base" id="beef" value="ビーフ"><label for="beef">ビーフ</label>
<input type="radio" name="base" id="chicken" value="チキン"><label for="chicken">チキン</label>
<p>トッピングは何種類?</p>
<input type="number" name="toppingNum" value="1">
<input type="submit" value="送信">
</form>
</body>
</html>
確認
ここまで書けたら一度確認する。サーブレットのCurryMain.javaを右クリックしてサーバーで実行を選択。以下のように表示されればOKだ。

controller.CurryMain.javaに追記
フォームから入力された値はpost通信で送信されてくるのでdoPostを以下のように追記
package controller;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import model.Curry;
import model.CurryLogic;
@WebServlet("/CurryMain")
public class CurryMain extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("WEB-INF/view/form.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//リクエストパラメータの文字化け帽子
request.setCharacterEncoding("UTF-8");
//(重要)リクエストパラメータの取得
String base=request.getParameter("base");
String toppingNum=request.getParameter("toppingNum");
//Curryインスタンスの作成
Curry curry = new Curry(base,toppingNum);
//CurryLogicインスタンスの作成
CurryLogic logic = new CurryLogic();
//executeメソッドの実行(curryインスタンスが完成する)
logic.execute(curry);
//リクエストスコープにcurryインスタンスを格納
request.setAttribute("curry", curry);
//viewにフォワード
request.getRequestDispatcher("WEB-INF/view/result.jsp").forward(request, response);
}
}
WEB-INF/view/result.jsp
スコープからインスタンスを取り出し、スクリプト式を使って値を出力する。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="model.Curry" %>
<%
Curry curry=(Curry)request.getAttribute("curry");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>カレーメーカー</title>
</head>
<body>
<p>今夜のカレーは「<%=curry.getToppingResult() %><%=curry.getBase() %>カレー」に決まりました!</p>
<a href="/curryapp/CurryMain">戻る</a>
</body>
</html>
完成
MVCによる流れは理解できてきたであろうか?
今回は見た目の装飾は行っていないが、スタイルをあててみるのもいいだろう。
コメント