JSP/Servlet
JSPとサーブレットの結合
最後にWebアプリケーションの開発においてJSPとサーブレットで機能を分け、より効率的に記述する方法について学習しましょう。基本的にJSPで記述してもサーブレットで記述してもどちらでも同じ処理が行えます。では、この二つの違いはなんでしょう?
一般的に、JSPは表示に関する記述をサーブレットはファイルやデータベースの処理といったロジックを記述する事に用いられます。ここでは、サンプルを通して、その使い分けについて説明していくことにしましょう。
掲示板の作成
JSPとServletの連携としての掲示板
では、実際にJSPとサーブレットの連携の例として、カレンダーのプログラムを紹介します。起動時には、現在の年・月のカレンダーが表示されますが、任意の年・月を選んで、「送信」ボタンを押すと、指定した年・月のカレンダーが得られるものです。
Calender.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>カレンダー</title>
<style type="text/css">
<!--
*{padding:5px; margin:0px;}
body{text-align:center;}
table{width:800px; background:white; border:2px black solid; border-collapse:collapse;}
th{border:1px black solid; background:#CCFFFF;}
td{border:1px black solid; text-align:right; padding:5px 20px 5px 20px;}
br{line-height:1em;}
-->
</style>
</head>
<body>
<b><%= request.getAttribute("year") %>年<%=request.getAttribute("month") %>月のカレンダー</b>
<br/>
<br/>
<%= request.getAttribute("calender") %>
<br/>
<b>カレンダーの変更</b>
<br/>
<div style="text-align:center;">
<form action="CalenderAccess" method="get">
<select id="year" name="year">
<%
int year = Integer.parseInt(request.getAttribute("year").toString());
int month = Integer.parseInt(request.getAttribute("month").toString());
for(int i = year-10; i <= year+10; i++){
%>
<option value="<%=i %>"
<%
if(i == year){
%>
selected
<%
}
%>
><%=i %>年</option>
<%
}
%>
</select>
<select id="moneth" name="month">
<%
for(int i = 1; i <= 12; i++){
%>
<option value="<%=i %>"
<%
if(i == month){
%>
selected
<%
}
%>
><%=i %>月</option>
<%
}
%>
</select>
<br/>
<br/>
<input type="submit" id="ok" name="ok" value="送信"/>
</form>
</div>
</body>
</html>
package day7;
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 java.util.*;
/**
* Servlet implementation class CalenderAccess
*/
@WebServlet("/day7/CalenderAccess")
public class CalenderAccess extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CalenderAccess() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
prepData(request);
RequestDispatcher dispatcher = request.getRequestDispatcher("Calender.jsp");
// フォワードによるページ遷移
dispatcher.forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
}
// 送信用のデータの作成
private void prepData(HttpServletRequest request){
// 変数初期化
int startday;
int lastday;
// カレンダーの取得
Calendar cal = Calendar.getInstance();
// 年が設定されていれば、その値を取得。そうでなければ、今年の年号を入れる
if(request.getParameter("year")==null){
request.setAttribute("year", cal.get(Calendar.YEAR)); // 現在の年
}else{
request.setAttribute("year", request.getParameter("year")); // 現在の年
}
if(request.getParameter("month")==null){
request.setAttribute("month", cal.get(Calendar.MONTH)+1); // 現在の月
}else{
request.setAttribute("month", request.getParameter("month")); // 与えらられた月
}
int year = Integer.parseInt(request.getAttribute("year").toString());
int month = Integer.parseInt(request.getAttribute("month").toString());
// 月初めの曜日(日-> 1)
cal.set(year, month - 1, 1);
startday = cal.get(Calendar.DAY_OF_WEEK);
// 月末の日付
cal.add(Calendar.MONTH, 1);
cal.add(Calendar.DATE, -1);
lastday = cal.get(Calendar.DATE);
// カレンダーのデータを作成する
int date = 1;
int maxday = 6 * 7;
StringBuilder sb = new StringBuilder();
sb.append("<table>");
sb.append("<tr>");
sb.append("<th style=¥"color:red;¥">日</th>");
sb.append("<th>月</th><th>火</th><th>水</th><th>木</th><th>金</th>");
sb.append("<th style=¥"color:blue;¥">土</th>");
sb.append("</tr>");
sb.append("<tr>");
for (int num = 1; num <= maxday; num++) {
if(num < startday || num > lastday + startday - 1){
sb.append("<td></td>");
}else{
sb.append("<td>"+date+"</td>");
date++;
}
if(num % 7 == 0){
sb.append("</tr>");
if(num > startday + lastday - 1){
break;
}
if(date < lastday){
sb.append("<tr>");
}else{
// 最後だったら、ループから抜ける
break;
}
}
}
sb.append("</table>");
// パラメータを設定
request.setAttribute("calender", sb);
return;
}
}
実行は、JSPであるCalender.jspではなく、サーブレットであるCalenderAccess.javaにしてください。
そのため、URLは、http://localhost:8080/jsp/day7/CalenderAccessとなります。結果、以下のようなカレンダーが出力されます。(図7-1.)
図7-1.purchase_historyテーブル![]() |
ここで、下に出ている「年」と「月」を変更し、「送信」ボタンを押すと、画面が切り替わり、指定した年・月のカレンダーに切り替わります。(図7-2.)
図7-2.LEFT OUTER JOINによる結合![]() |
GET送信であることから、URLの末尾に、「?year=2016&month=10…」といった具合にyeare(年)およびmonth(月)のパラメータが送付されていることが分かります。
アクセスの仕組み
ではこのプログラムの仕組みを見てみましょう。まず、大まかなアクセスの仕組みを図にすると以下の通りになります。(図7-3.)
図7-3.RIGHT OUTER JOINによる結合![]() |
初回のアクセスでは、現在の「年」と「月」をもとにして、カレンダーを作成し、「年」・「月」およびカレンダーのデータとして、Calender.jspに送信し、それが画面に出力されます。
次に、「送信」ボタンが押されると、画面上で選択された「年」と「月」が送られて、それを元にカレンダーが表示されます。
パラメータの取得
では、CalenderAccess.javaの中の、doGet()メソッドで、初回アクセスと、「送信」ボタンが押されたときのアクセスは、どのようにして区別しているのでしょうか。
結論から先に言うと、prepDataメソッドの中の「GET送信時のパラメータの有無」で区別しています。送信時にパラメータが設定されていると、requestのgetParamaterメソッドでデータを取得できます。したがって、その値が取れないということは、初回アクセスということになります。(図7-4.)
図7-4.LEFT OUTER JOINの内容![]() |
アトリビュート
次は、得られた「年」および「月」をもとに、カレンダーを作ります。カレンダーはテーブル(table)を用いて作ります。このサンプルでは、65行目から105行目までの間でその処理を行っています。
これらが完成すると、次は「年」「月」「カレンダー」のデータをCalender.jspに送信する必要があります。そのために必要になるのが、requestオブジェクトのsetAttribute()および、getAttribute()メソッドです。
これらは、requestオブジェクトの属性として、送信するデータを設定・取得ができるというものです。使い方は以下のようになります。
requestオブジェクトの属性の値の設定設定する値は、オブジェクトになります。そのため、設定側と取得側できちんと型を合わせておく必要があるので、注意が必要です。なお、CalenderAccess.javaの54行目から66行の間でこれら一連の処理が行われています。
フォワード
属性の設定が終わったら、次は属性の値を持ったままでページ遷移を行う必要があります。そのためには、フォワードと呼ばれる処理を行う必要があります。このサンプルでは、CalenderAccess.javaの34行目から36行の間で行われています。
フォワードの処理// フォワードによるページ遷移
dispatcher.forward(request, response);
getRequestDispatcherメソッドは、引数にURLを指定し、そのURLに対するRequestDispatcherオブジェクトを生成します。URLはコンテキストルートから/(スラッシュ)を含めて絶対パスで指定するか、呼び出すプログラムからの相対パスで指定します。
生成されたオブジェクトの、forwardメソッドを利用すれば、指定されたページに遷移できます。フォワードには引数として、request並びにresponseを必要とします。これにより、requestの属性が、遷移先のページで取得できます。(図7-5.)
図7-5.RIGHT OUTER JOINの内容![]() |
以上がこのプログラムの大まかな仕組みです。カレンダーを生成する仕組みなど、細かい点に関する説明は省略します。興味がある方は是非とも解析してみてください。
以上で基本編の開設は終わりです。しかし、より実用的なWebアプリを作成するためには、これだけの知識では不十分です。更に学習を進めるためには、応用編をご覧ください。













