今回は受講生(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クラスに関してはここなどを参考にしよう。
コメント