MVC練習2(カレートッピング)

JSP&Servlet

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 int toppingNum;//5などが入る
	private String topping;//「こんにゃくゴーヤきゅうり」などの文字列
	public Curry() {}
	public Curry(String base,int toppingNum) {
		this.base=base;
		this.toppingNum=toppingNum;
	}
	public String getBase() {
		return base;
	}
	public void setBase(String base) {
		this.base = base;
	}
	public int getToppingNum() {
		return toppingNum;
	}
	public void setToppingNum(int toppingNum) {
		this.toppingNum = toppingNum;
	}
	public String getTopping() {
		return topping;
	}
	public void setTopping(String topping) {
		this.topping = topping;
	}

}

model.CurryLogic.java

package model;

import java.util.Random;

public class CurryLogic {
	final String[] TOPPINGS ={
			"大根","セロリ","里芋","カブ","ゴーヤ","キュウリ","カツオのたたき","ラム肉",
			"鯖の水煮","ブリ","タコ","ちくわ","魚肉ソーセージ","こんにゃく","ツナ缶",
			"納豆","アボガド","レーズン","あげ玉",
	};
	public void execute(Curry curry) {
		Random rand=new Random();
		String topping="";
		for(int i=0;i<Math.min(curry.getToppingNum(), TOPPINGS.length);i++){
			//indexを抽選(ループを回すごとに範囲が狭まる)
			int index = rand.nextInt(TOPPINGS.length-i);
			//抽選された結果を文字列連結
			topping += TOPPINGS[index];
			//末尾の項目を抽選されたindexのところに上書き
			TOPPINGS[index]=TOPPINGS[TOPPINGS.length-1-i];
		}
		//トッピングをセット
		curry.setTopping(topping);
	}
}

controller.CurryMain.java

処理の流れを考えながらまずはdoGetを作成する。form.jspのフォワードするだけの処理だ。(doPostはカラにしておく)

package controller;

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 model.Curry;
import model.CurryLogic;

@WebServlet("/CurryMain")
public class CurryMain extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//jspに処理を転送するフォワード処理
		RequestDispatcher rd=
				request.getRequestDispatcher("/WEB-INF/view/form.jsp");
		rd.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="ポーク"><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">
<input type="submit" value="送信">
</form>
</body>
</html>

確認

ここまで書けたら一度確認する。サーブレットのCurryMain.javaを右クリックしてサーバーで実行を選択。以下のように表示されればOKだ。

controller.CurryMain.javaに追記

フォームから入力された値はpost通信で送信されてくるのでdoPostを以下のように追記

package controller;

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 model.Curry;
import model.CurryLogic;

@WebServlet("/CurryMain")
public class CurryMain extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher rd=
				request.getRequestDispatcher("/WEB-INF/view/form.jsp");
		rd.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		String base=request.getParameter("base");
		int toppingNum=Integer.parseInt(request.getParameter("toppingNum"));
		Curry curry=new Curry(base,toppingNum);
		CurryLogic logic=new CurryLogic();;
		logic.execute(curry);
		request.setAttribute("curry", curry);
		RequestDispatcher rd=
				request.getRequestDispatcher("/WEB-INF/view/result.jsp");
		rd.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.getTopping() %><%=curry.getBase() %>カレー」に決まりました!</p>
<a href="/curryapp/CurryMain">戻る</a>
</body>
</html>

完成

MVCによる流れは理解できてきたであろうか?
今回は見た目の装飾は行っていないが、スタイルをあててみるのもいいだろう。

コメント

タイトルとURLをコピーしました