MVCに分割してじゃんけん処理を作成してみよう3

JSP&Servlet

MVCに分割してじゃんけんの処理を作成してみよう。今回はアプリケーションスコープを使ってトータル勝数、トータル負け数を表示する

実行例

  • 以下のurlをいれリクエストを送ると以下のような手を選ぶフォームが表示される
  • 手を選択し勝負ボタンを押すと結果が表示される。TotalWinとLoseはこのアプリで遊んだ人のすべての結果が集計される
  • 戻るを押すと最初から
  • 勝敗をクリアを押すと個人の生成だけクリアされる

model.Jyan.java

作成

データモデル1(Session用)

  • 実行例を見ると、
    自分の手
    PCの手
    結果
    勝数
    負け数
    を表示している。その5つをフィールドに持つJyanクラスを以下のように作成する
package model;

import java.io.Serializable;

public class Jyan implements Serializable{
	private String userHand;
	private String pcHand;
	private String result;
	private int win;
	private int lose;
	public String getUserHand() {
		return userHand;
	}
	public void setUserHand(String userHand) {
		this.userHand = userHand;
	}
	public String getPcHand() {
		return pcHand;
	}
	public void setPcHand(String pcHand) {
		this.pcHand = pcHand;
	}
	public String getResult() {
		return result;
	}
	public void setResult(String result) {
		this.result = result;
	}
	public int getWin() {
		return win;
	}
	public void setWin(int win) {
		this.win = win;
	}
	public int getLose() {
		return lose;
	}
	public void setLose(int lose) {
		this.lose = lose;
	}

}

データモデル2(Application用)

  • トータル勝ち数、トータル負け数を管理するモデルを作成する(model.Total.java)
package model;

import java.io.Serializable;

public class Total implements Serializable{
	private int totalWin;
	private int totalLose;
	public int getTotalWin() {
		return totalWin;
	}
	public void setTotalWin(int totalWin) {
		this.totalWin = totalWin;
	}
	public int getTotalLose() {
		return totalLose;
	}
	public void setTotalLose(int totalLose) {
		this.totalLose = totalLose;
	}
	

}

controller.JyanMain.java

  • MVCに分割して作成する場合、リクエストを受け取るのはサーブレットの役割だ。
  • 最初のリクエストはフォームを表示する処理なので、シンプルに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("/JyanMain")
public class JyanMain 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

  • 実行例になるようにformを作成する
<%@ 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="JyanMain" method="post">
<label><input type="radio" name="userHand" value="0" required>グー</label>
<label><input type="radio" name="userHand" value="1">チョキ</label>
<label><input type="radio" name="userHand" value="2">パー</label>
<button type="submit">勝負</button>
</form>
</body>
</html>
  • JyanMainサーブレットから実行してみよう以下のようにフォームが表示されれば成功だ

model.JyanLogic.java

  • フォームからユーザーが選択した手を取得できるのでその手をJyanインスンタンスに覚えさせる
  • JyanLogicクラスでそのJyanインスタンス とTotalインスタンスをを引数に受取り、内部でPCの手をランダムに作成し、判定を行ないJyanインスタンスとTotalインスンタンスを更新させる処理を以下のように作成する
  • 勝敗数を更新する
package model;

public class JyanLogic {
	public static final String[] HANDS= {"グー","チョキ","パー"};
	public static final String[] RESULTS= {"あいこ","あなたの負け","あなたの勝ち"};
	public void execute(Jyan jyan,Total total) {
		int userHand = Integer.parseInt(jyan.getUserHand());
		int pcHand = (int)(Math.random()*3);
		int diff = (userHand+3 - pcHand) % 3;
		jyan.setUserHand(HANDS[userHand]);
		jyan.setPcHand(HANDS[pcHand]);
		jyan.setResult(RESULTS);
		if(diff == 2) {
			jyan.setWin(jyan.getWin()+1);
			total.setTotalWin(total.getTotalWin()+1);
		}else if(diff==1) {
			jyan.setLose(jyan.getLose()+1);
			total.setTotalLose(total.getTotalLose()+1);
		}
	}
	

}

controller.JyanMain.javaへの追記

  • フォームからユーザーが選んだ手が0,1,2のいずれかで飛んでくるのでdoPostを以下のように追記する
  • アプリケーションスコープからTotalインスタンスを取得す(なければ新規に作成する)
  • セッションスコープからjyanインスタンスを取得する(なければ新規に作成する)

package controller;

import java.io.IOException;

import jakarta.servlet.ServletContext;
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 jakarta.servlet.http.HttpSession;

import model.Jyan;
import model.JyanLogic;
import model.Total;

@WebServlet("/JyanMain")
public class JyanMain extends HttpServlet {
	private static final long serialVersionUID = 1L;
	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 {
		ServletContext application = this.getServletContext();
		Total total=(Total)application.getAttribute("total");
		if(total == null) {
			total=new Total();
		}
		String userHand=request.getParameter("userHand");
		HttpSession session = request.getSession();
		Jyan jyan = (Jyan)session.getAttribute("jyan");
		if(jyan==null) {
			 jyan = new Jyan();
		}
		jyan.setUserHand(userHand);
		JyanLogic logic = new JyanLogic();
		logic.execute(jyan,total);
		session.setAttribute("jyan", jyan);
		application.setAttribute("total", total);
		request.getRequestDispatcher("WEB-INF/view/result.jsp").forward(request, response);

	}

}

WEB-INF/view/result.jsp

  • すべての情報を持っているjyanインスタンスをセッションスコープから取得しtotalイン住んたすをアプリケーションスコープから取り出し、情報を表示する
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="model.Jyan" %>
<%@ page import="model.Total" %>
<%
Jyan jyan=(Jyan)session.getAttribute("jyan");
Total total=(Total)application.getAttribute("total");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>じゃんけん</title>
</head>
<body>
<p>あなたは<%=jyan.getUserHand() %></p>
<p>PCは<%=jyan.getPcHand() %></p>
<p><%=jyan.getResult() %></p>
<p>Win:<%=jyan.getWin() %></p>
<p>Lose:<%=jyan.getLose() %></p>
<p>TotalWin:<%=total.getTotalWin() %></p>
<p>TotalLose:<%=total.getTotalLose() %></p>
<p><a href="JyanMain">戻る</a></p>
<a href="JyanMain?action=reset">(勝敗をクリア)</a>

</body>
</html>

controller.JyanMain.javaの追記

  • 勝敗をクリアを押されたときの処理を以下のように追記する

package controller;

import java.io.IOException;

import jakarta.servlet.ServletContext;
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 jakarta.servlet.http.HttpSession;

import model.Jyan;
import model.JyanLogic;
import model.Total;

@WebServlet("/JyanMain")
public class JyanMain extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String action = request.getParameter("action");
		if(action != null && action.equals("reset")) {
			HttpSession session = request.getSession();
			session.removeAttribute("jyan");
		}
		request.getRequestDispatcher("WEB-INF/view/form.jsp").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletContext application = this.getServletContext();
		Total total=(Total)application.getAttribute("total");
		if(total == null) {
			total=new Total();
		}
		String userHand=request.getParameter("userHand");
		HttpSession session = request.getSession();
		Jyan jyan = (Jyan)session.getAttribute("jyan");
		if(jyan==null) {
			 jyan = new Jyan();
		}
		jyan.setUserHand(userHand);
		JyanLogic logic = new JyanLogic();
		logic.execute(jyan,total);
		session.setAttribute("jyan", jyan);
		application.setAttribute("total", total);
		request.getRequestDispatcher("WEB-INF/view/result.jsp").forward(request, response);

	}

}

完成

実行してみよう。実行例どおりに遊べれば成功だ。

コメント

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