MVC練習3(誕生日カウンター)

JSP&Servlet

今回は受講生(K氏)からのお題を題材にMVCに分けて行う開発の学習しよう。

お題

ホスト名/birthday/BirthdayMain

上記のURLでブラウザからアクセスすると。以下のようなフォームが表示される

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

以下のように出力される

もし実行した日が誕生日だったら以下のメッセージ。


戻るを押すと最初に戻る

作成

ファイル構成

model

model.Birthday.java //javaBeansの仕様を満たしたクラス
model.BirthdayLogic.java //入力された誕生日をもとにインスタンスを完成させるクラス

controller

controller.BirthdayMain.java //HttpServletクラスを継承して作成する(サーブレット)

view

/WEB-INF/view/form.jsp //フォームを表示する
/WEB-INF/view/result.jsp //結果を表示する

作成

model.Birthday.java

結果画面を見て、何が必要なのかを考慮し以下のようなクラスを作成する。

package model;

import java.io.Serializable;

public class Birthday implements Serializable{
	private int month;//ユーザーが入力した誕生月
	private int date;//ユーザーが入力した誕生日
	private String msg;//表示するメッセージ
	public Birthday() {}
	public Birthday(int month,int date) {
		this.month=month;
		this.date=date;
	}
	public int getMonth() {
		return month;
	}
	public void setMonth(int month) {
		this.month = month;
	}
	public int getDate() {
		return date;
	}
	public void setDate(int date) {
		this.date = date;
	}
	public String getMsg() {
		return msg;
	}
	public void setMsg(String msg) {
		this.msg = msg;
	}
}

model.BirthdayLogic.java

package model;

import java.util.Calendar;

public class BirthdayLogic {
	//誕生月と誕生日の情報を持ってるインスタンスが引数に入る
	public void execute(Birthday bd) {
		//今日の日付情報を持つカレンダーインスタンを作成
		Calendar today=Calendar.getInstance();
		//今日のyearを取得
		int nowYear=today.get(Calendar.YEAR);
		//次の誕生日用のインスタンスを作成
		Calendar bDay=Calendar.getInstance();
		//次の誕生日が年内にあると仮定してインスタンスを作成。
		//この際、月は(0-11)で扱われることに注意!
		bDay.set(nowYear, bd.getMonth()-1,bd.getDate());
		//1970年1月1日からのミリ秒を算出し、それを比較する
		if(today.getTimeInMillis()>bDay.getTimeInMillis()) {
			//もし、年内の誕生日が過ぎていれば来年に設定
			bDay.set(Calendar.YEAR,nowYear+1);
		}
		//次の誕生日と本日の差分をミリ秒で取得
		long diff=bDay.getTimeInMillis()-today.getTimeInMillis();
		//1日をミリ秒で表す
		int millisOfDay=1000*60*60*24;
		//差分を日数で表す
		int diffDays=(int)(diff/millisOfDay);
		String msg;
		if(diffDays==0) {
			msg="今日はあなたの誕生日です。おめでとうございます。";
		}else {
			msg="次の誕生日まであと"+diffDays+"日です。";
		}
		//インスタンスにセット
		bd.setMsg(msg);
	}
}

controller.BirthdayMain.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.Birthday;
import model.BirthdayLogic;

@WebServlet("/BirthdayMain")
public class BirthdayMain extends HttpServlet {
	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 {
		
	}

}

/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>
<p>あなたの誕生日を入力してください。</p>
<form action="/birthday/BirthdayMain" method="post">
<input type="number" step="1" min="1" max="12" name="month">月
<input type="number" step="1" min="1" max="31" name="date">日
<input type="submit" value="送信">
</form>
</body>
</html>

確認

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

controller.BirthdayMain.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.Birthday;
import model.BirthdayLogic;

@WebServlet("/BirthdayMain")
public class BirthdayMain extends HttpServlet {
	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 {
		int month=Integer.parseInt(request.getParameter("month"));
		int date=Integer.parseInt(request.getParameter("date"));
		//Birthdayインスタンスを作成
		Birthday bd=new Birthday(month,date);
		//ロジックインスタンスを作成
		BirthdayLogic logic =new BirthdayLogic();
		//表示に必要な情報を持ったインスタンスが出来上がる
		logic.execute(bd);
		//リクエストスコープにインスタンスをセット
		request.setAttribute("bd", bd);
		//フォワード処理
		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.Birthday" %>
<%
Birthday bd=(Birthday)request.getAttribute("bd");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>次の誕生日カウンター</title>
</head>
<body>
<p><%=bd.getMonth() %>月<%=bd.getDate() %>日生まれのあなた。</p>
<p><%=bd.getMsg() %></p>
<a href="/birthday/BirthdayMain">戻る</a>
</body>
</html>

完成

今回はCalendarクラスの活用がポイントとなる。Calendarクラスに関してはここなどを参考にしよう。

コメント

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