
サーブレット&JSPの基本|セッションスコープを使ったWebアプリ作成
入力、確認、完了の画面をつなぐ。セッションスコープでリクエストをまたぐWebアプリを作ろう
リクエストスコープは、サーブレットからJSPへ一時的にデータを渡すときに便利なスコープです。
しかし、リクエストスコープに保存したインスタンスは、レスポンスが返ると利用できなくなります。そのため、次のリクエストでも同じインスタンスを使いたい場合には向いていません。
そこで使うのがセッションスコープです。
セッションスコープにインスタンスを保存すると、レスポンス後もデータを残すことができます。そのため、入力画面、確認画面、完了画面のように、複数の画面をまたいで同じ情報を使いたい場合に役立ちます。
この記事では、セッションスコープを使って研修コース申込機能を作成します。利用者が申込ID、確認コード、氏名を入力し、確認画面で内容を確認してから、完了画面へ進むアプリケーションです。
入力された申込情報は、サーブレットでJavaBeansとして作成し、セッションスコープに保存します。確認画面ではセッションスコープから申込情報を取得して表示します。登録実行時にも、セッションスコープから同じインスタンスを取得して、登録処理を担当するモデルに渡します。
作成するWebアプリケーションの流れ
今回作成する研修コース申込機能は、次の3つの画面で構成します。
画面遷移
| 画面 | 内容 |
|---|---|
| 研修コース申込入力画面 | 申込ID、確認コード、氏名を入力する |
| 研修コース申込確認画面 | 入力した申込IDと氏名を確認する |
| 研修コース申込完了画面 | 申込完了メッセージを表示する |
最初に、ブラウザからTrainingEntryServletへアクセスします。
すると、入力画面であるtrainingEntryForm.jspへフォワードされます。利用者が情報を入力して確認ボタンをクリックすると、POSTリクエストでTrainingEntryServletへ送信されます。
サーブレットは入力内容をもとにTrainingEntryインスタンスを作成し、セッションスコープに保存します。その後、確認画面であるtrainingEntryConfirm.jspへフォワードします。
確認画面で申込ボタンをクリックすると、action=doneというリクエストパラメータ付きでTrainingEntryServletへGETリクエストが送られます。サーブレットはセッションスコープから申込情報を取得し、TrainingEntryLogicに登録処理を依頼します。最後に、不要になった申込情報をセッションスコープから削除し、完了画面へフォワードします。
図1:研修コース申込機能の画面遷移

この図から分かること
このアプリケーションでは、入力画面、確認画面、完了画面の順に画面が進みます。
入力画面で送信された申込情報は、確認画面だけでなく、完了処理を行うときにも必要です。確認画面から完了処理へ進むときは、別のリクエストになります。
そのため、申込情報をリクエストスコープではなくセッションスコープに保存します。セッションスコープに保存しておけば、入力後の確認画面でも、確認画面から申込を実行するときでも、同じTrainingEntryインスタンスを利用できます。
作成するファイル
今回のアプリケーションでは、MVCモデルに沿って6つのファイルを作成します。
作成するファイル一覧
| ファイル | 種類 | 役割 |
|---|---|---|
| TrainingEntry.java | モデル JavaBeans | 申込ID、氏名、確認コードを持つ |
| TrainingEntryLogic.java | モデル 処理クラス | 申込処理を行う |
| TrainingEntryServlet.java | コントローラ サーブレット | リクエストを受け取り、画面遷移と処理を制御する |
| trainingEntryForm.jsp | ビュー JSP | 申込入力画面を表示する |
| trainingEntryConfirm.jsp | ビュー JSP | 申込確認画面を表示する |
| trainingEntryDone.jsp | ビュー JSP | 申込完了画面を表示する |
TrainingEntry.javaは、入力された申込情報をまとめて保持するJavaBeansです。
TrainingEntryLogic.javaは、申込処理を担当するモデルです。今回は学習用のサンプルなので、ファイルやデータベースへの登録は行わず、登録できたものとしてtrueを返します。
TrainingEntryServlet.javaは、リクエストを受け取り、入力画面、確認画面、完了画面のどこへ進むかを判断します。
3つのJSPファイルは、画面表示を担当します。
MVCモデルとしての構成
今回の研修コース申込機能は、MVCモデルの形で作成します。
MVCモデルでの役割
| MVCの要素 | 今回の担当 | 内容 |
|---|---|---|
| Model | TrainingEntry.java TrainingEntryLogic.java | 申込情報の保持と申込処理を担当する |
| View | trainingEntryForm.jsp trainingEntryConfirm.jsp trainingEntryDone.jsp | 入力画面、確認画面、完了画面を表示する |
| Controller | TrainingEntryServlet.java | リクエストを受け取り、処理と画面遷移を制御する |
MVCモデルでは、データ、処理、表示、制御を分けて作ります。
今回のアプリケーションでは、TrainingEntryServletが中心となり、必要に応じてモデルを使い、表示するJSPを切り替えます。
図2:セッションスコープを使った研修コース申込機能の構成

この図から分かること
このアプリケーションでは、TrainingEntryServletがコントローラとしてリクエストを受け取ります。
入力画面から送信された申込情報は、TrainingEntryインスタンスとして作成され、セッションスコープに保存されます。確認画面では、そのTrainingEntryインスタンスをセッションスコープから取得して表示します。
確認画面で申込を実行すると、TrainingEntryServletは再び呼び出されます。このときも、セッションスコープからTrainingEntryインスタンスを取得できるため、登録処理に利用できます。
登録処理が終わったら、不要になったTrainingEntryインスタンスをセッションスコープから削除します。
処理全体の流れ
今回のアプリケーションは、3つのリクエストで動きます。
リクエスト① 申込入力画面を表示する
| 順番 | 内容 |
|---|---|
| 1 | ブラウザからTrainingEntryServletへGETリクエストを送る |
| 2 | TrainingEntryServletのdoGetメソッドが実行される |
| 3 | actionの値がnullなので、申込開始と判断する |
| 4 | trainingEntryForm.jspへフォワードする |
| 5 | 申込入力画面が表示される |
最初にブラウザでアクセスするURLは次のようになります。
この時点では、actionというリクエストパラメータは送信しません。そのため、doGetメソッドではactionの値がnullになります。
リクエスト② 入力内容を確認する
入力画面で確認ボタンをクリックすると、POSTリクエストがTrainingEntryServletへ送信されます。
POST時の流れ
| 順番 | 内容 |
|---|---|
| 1 | 入力画面で確認ボタンをクリックする |
| 2 | TrainingEntryServletのdoPostメソッドが実行される |
| 3 | 申込ID、氏名、確認コードをリクエストパラメータから取得する |
| 4 | TrainingEntryインスタンスを作成する |
| 5 | TrainingEntryインスタンスをセッションスコープに保存する |
| 6 | trainingEntryConfirm.jspへフォワードする |
| 7 | 確認画面が表示される |
ここで重要なのは、入力された申込情報をセッションスコープに保存する点です。
確認画面の表示だけならリクエストスコープでもできそうに見えます。しかし、確認画面から申込実行へ進むときには、別のGETリクエストが送られます。
その次のリクエストでも同じ申込情報を使うため、セッションスコープに保存しておく必要があります。
リクエスト③ 申込を実行する
確認画面で申込リンクをクリックすると、action=doneを付けてTrainingEntryServletへGETリクエストを送ります。
申込実行時の流れ
| 順番 | 内容 |
|---|---|
| 1 | 確認画面で申込をクリックする |
| 2 | TrainingEntryServletへaction=done付きのGETリクエストを送る |
| 3 | doGetメソッドが実行される |
| 4 | actionの値がdoneなので、申込実行と判断する |
| 5 | セッションスコープからTrainingEntryインスタンスを取得する |
| 6 | TrainingEntryLogicに申込処理を依頼する |
| 7 | セッションスコープからTrainingEntryインスタンスを削除する |
| 8 | trainingEntryDone.jspへフォワードする |
| 9 | 申込完了画面が表示される |
このように、入力画面から確認画面、確認画面から完了画面へ進む間に、同じ申込情報を保持するためにセッションスコープを利用します。
リクエストパラメータで処理を振り分ける
このアプリケーションでは、TrainingEntryServletのdoGetメソッドが2つの場面で実行されます。
1つ目は、プログラム開始時に申込入力画面を表示する場面です。
2つ目は、確認画面から申込を実行する場面です。
同じdoGetメソッドでも、場面によって行う処理が異なります。そのため、どこから来たリクエストなのかを判断する必要があります。
そこで、actionというリクエストパラメータを使います。
actionによる処理の振り分け
| actionの値 | 判断する内容 | フォワード先 |
|---|---|---|
| null | 申込開始のリクエスト | WEB-INF/jsp/trainingEntryForm.jsp |
| done | 申込実行のリクエスト | WEB-INF/jsp/trainingEntryDone.jsp |
プログラム開始時は、actionを送信しません。そのため、actionの値はnullになります。
確認画面から申込を実行するときは、action=doneを付けてリクエストします。そのため、doGetメソッドでは申込実行のリクエストだと判断できます。
図3:actionパラメータによる処理の振り分け

この図から分かること
同じTrainingEntryServletのdoGetメソッドでも、プログラム開始時と申込実行時では処理が異なります。
そこで、actionというリクエストパラメータを使って、どの場面から呼び出されたのかを判断します。
actionが送られていない場合は、申込開始として入力画面へ進みます。action=doneが送られている場合は、申込実行としてセッションスコープから申込情報を取得し、登録処理を行います。
リクエストとサーブレットクラスの対応
今回のアプリケーションでは、すべてのリクエストをTrainingEntryServletに集めています。
GETリクエストでもPOSTリクエストでも、まずTrainingEntryServletが受け取ります。そのうえで、doGetやdoPostの中で処理を振り分けます。
ただし、必ずこの形にしなければならないわけではありません。
リクエストごとに別々のサーブレットクラスを作る方法もあります。どのリクエストをどのサーブレットで処理するかは、アプリケーションの規模、複雑さ、設計方針によって決めます。
今回の設計
| リクエスト | 実行されるメソッド | 主な処理 |
|---|---|---|
| 申込開始 | doGet | 入力画面へフォワードする |
| 入力内容の確認 | doPost | 入力値を取得し、セッションスコープに保存する |
| 申込実行 | doGet | action=doneで判断し、申込処理を行う |
1つのサーブレットに処理を集めると、申込機能全体の流れを1つのクラスで追いやすくなります。
一方で、処理が増えすぎるとサーブレットが長くなりやすいので、機能の規模に応じて設計を考えることが大切です。
JavaBeansを作成する
まず、申込情報を表すJavaBeansを作成します。
TrainingEntry.javaには、申込ID、氏名、確認コードをフィールドとして用意します。
登録する申込情報を表すJavaBeansの例
ファイル名: TrainingEntry.java
package model;
import java.io.Serializable;
public class TrainingEntry implements Serializable {
private String entryId;
private String name;
private String passcode;
public TrainingEntry() { }
public TrainingEntry(String entryId, String name, String passcode) {
this.entryId = entryId;
this.name = name;
this.passcode = passcode;
}
public String getEntryId() {
return entryId;
}
public String getName() {
return name;
}
public String getPasscode() {
return passcode;
}
}TrainingEntry.javaは、modelパッケージに作成します。
このクラスは、申込に必要な情報を1つのインスタンスとしてまとめる役割を持ちます。
TrainingEntry.javaのポイント
TrainingEntry.javaは、セッションスコープに保存するためのJavaBeansです。
JavaBeansとして確認する点
| 確認項目 | 内容 |
|---|---|
| パッケージ | package modelでmodelパッケージに所属している |
| 直列化 | Serializableを実装している |
| publicなクラス | public class TrainingEntryとして作成している |
| 引数なしコンストラクタ | public TrainingEntry() { }を用意している |
| フィールドのカプセル化 | entryId、name、passcodeをprivateにしている |
| getter | getEntryId、getName、getPasscodeを用意している |
セッションスコープには、関連する情報をまとめたJavaBeansを保存すると扱いやすくなります。
今回は、申込ID、氏名、確認コードをTrainingEntryインスタンスにまとめています。
申込処理を行うモデルを作成する
次に、申込処理を担当するモデルを作成します。
今回は学習用のサンプルなので、実際にファイルやデータベースへ登録する処理は行いません。登録処理を行ったものとしてtrueを返します。
申込処理を行うモデルの例
ファイル名: TrainingEntryLogic.java
package model;
public class TrainingEntryLogic {
public boolean execute(TrainingEntry entry) {
// 申込処理
// 実際のファイル登録やデータベース登録は行わない
return true;
}
}TrainingEntryLogic.javaもmodelパッケージに作成します。
このクラスは、申込処理の担当です。画面表示は行いません。また、リクエストパラメータを直接取得することもありません。
TrainingEntryLogic.javaの役割
TrainingEntryLogic.javaは、登録処理を担当するモデルです。
今回の処理では、TrainingEntryインスタンスを受け取り、申込処理を実行したものとしてtrueを返します。
処理の考え方
| 処理 | 内容 |
|---|---|
| 引数 | TrainingEntryインスタンスを受け取る |
| 実行内容 | 申込処理を行う |
| 今回のサンプル | 実際の登録処理は行わずtrueを返す |
現段階では、セッションスコープを使った画面遷移とデータ共有の仕組みを理解することが目的です。
そのため、データベースなどへの登録処理は扱わず、登録処理の形だけを確認します。
コントローラを作成する
次に、申込に関するリクエストを処理するサーブレットを作成します。
TrainingEntryServlet.javaは、今回のアプリケーションのコントローラです。
doGetメソッドでは、actionの値によって入力画面を表示するのか、申込処理を実行するのかを判断します。
doPostメソッドでは、入力画面から送信された申込情報を取得し、TrainingEntryインスタンスを作成して、セッションスコープに保存します。
研修コース申込に関するリクエストを処理するコントローラの例
ファイル名: TrainingEntryServlet.java
package servlet;
import java.io.IOException;
import jakarta.servlet.RequestDispatcher;
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.TrainingEntry;
import model.TrainingEntryLogic;
@WebServlet("/TrainingEntryServlet")
public class TrainingEntryServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// フォワード先
String forwardPath = null;
// サーブレットクラスの動作を決定するactionの値を取得
String action = request.getParameter("action");
// 申込開始をリクエストされたときの処理
if (action == null) {
// フォワード先を設定
forwardPath = "WEB-INF/jsp/trainingEntryForm.jsp";
}
// 確認画面から申込実行をリクエストされたときの処理
else if (action.equals("done")) {
// セッションスコープに保存された申込情報を取得
HttpSession session = request.getSession();
TrainingEntry entry =
(TrainingEntry) session.getAttribute("entryUser");
// 申込処理の呼び出し
TrainingEntryLogic logic = new TrainingEntryLogic();
logic.execute(entry);
// 不要となったセッションスコープ内のインスタンスを削除
session.removeAttribute("entryUser");
// 申込後のフォワード先を設定
forwardPath = "WEB-INF/jsp/trainingEntryDone.jsp";
}
// 設定されたフォワード先にフォワード
RequestDispatcher dispatcher =
request.getRequestDispatcher(forwardPath);
dispatcher.forward(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// リクエストパラメータの取得
request.setCharacterEncoding("UTF-8");
String entryId = request.getParameter("entryId");
String name = request.getParameter("name");
String passcode = request.getParameter("passcode");
// 申込情報を設定
TrainingEntry entryUser =
new TrainingEntry(entryId, name, passcode);
// セッションスコープに申込情報を保存
HttpSession session = request.getSession();
session.setAttribute("entryUser", entryUser);
// フォワード
RequestDispatcher dispatcher =
request.getRequestDispatcher(
"WEB-INF/jsp/trainingEntryConfirm.jsp");
dispatcher.forward(request, response);
}
}TrainingEntryServlet.javaは、servletパッケージに作成します。
URLパターンは/TrainingEntryServletです。ブラウザからhttp://localhost:8080/study/TrainingEntryServletへアクセスすると、doGetメソッドが実行されます。
doGetメソッドの役割
doGetメソッドは、2つの場面で実行されます。
1つ目は、アプリケーションを開始して入力画面を表示するときです。
2つ目は、確認画面から申込を実行するときです。
この2つを区別するために、actionというリクエストパラメータを使います。
doGetメソッドの分岐
| actionの値 | 処理内容 |
|---|---|
| null | 申込入力画面へフォワードする |
| done | セッションスコープから申込情報を取得し、申込処理を行う |
最初にアクセスしたときは、actionを送信しません。そのため、actionの値はnullになります。
確認画面の申込リンクでは、TrainingEntryServlet?action=doneへアクセスします。そのため、actionの値がdoneになり、申込実行の処理へ進みます。
doPostメソッドの役割
doPostメソッドは、入力画面から確認ボタンをクリックしたときに実行されます。
trainingEntryForm.jspのフォームでは、method属性にpostを指定しています。そのため、確認ボタンをクリックするとPOSTリクエストが送信されます。
doPostメソッドでは、リクエストパラメータから入力値を取得し、TrainingEntryインスタンスを作成します。
doPostメソッドの処理
| 順番 | 内容 |
|---|---|
| 1 | request.setCharacterEncodingで文字コードを指定する |
| 2 | entryId、name、passcodeを取得する |
| 3 | TrainingEntryインスタンスを作成する |
| 4 | request.getSessionでHttpSessionを取得する |
| 5 | session.setAttributeでセッションスコープに保存する |
| 6 | trainingEntryConfirm.jspへフォワードする |
ここで作成したTrainingEntryインスタンスは、確認画面でも申込実行時でも使います。
そのため、リクエストスコープではなく、セッションスコープに保存しています。
セッションスコープに保存する処理
TrainingEntryServlet.javaでは、次の流れでセッションスコープに申込情報を保存しています。
まず、入力値をもとにTrainingEntryインスタンスを作成します。
次に、request.getSessionでHttpSessionインスタンスを取得します。
最後に、session.setAttributeでTrainingEntryインスタンスを保存します。
保存処理の対応
| 処理 | 内容 |
|---|---|
| new TrainingEntry(entryId, name, passcode) | 申込情報を持つインスタンスを作成する |
| request.getSession | HttpSessionインスタンスを取得する |
| session.setAttribute("entryUser", entryUser) | entryUserという属性名でセッションスコープに保存する |
保存時の属性名はentryUserです。
確認画面や申込実行時には、このentryUserという属性名を使ってセッションスコープからTrainingEntryインスタンスを取得します。
セッションスコープから取得して削除する処理
確認画面から申込を実行すると、TrainingEntryServletのdoGetメソッドが呼ばれます。
このとき、actionの値はdoneです。
doGetメソッドでは、セッションスコープからentryUserを取得し、TrainingEntryLogicに渡して申込処理を行います。
申込処理が終わったら、session.removeAttributeでentryUserを削除します。
取得と削除の対応
| 処理 | 内容 |
|---|---|
| session.getAttribute("entryUser") | セッションスコープから申込情報を取得する |
| (TrainingEntry) | Object型からTrainingEntry型へキャストする |
| logic.execute(entry) | 申込処理を実行する |
| session.removeAttribute("entryUser") | 不要になった申込情報を削除する |
セッションスコープはレスポンス後も情報が残ります。
便利な反面、不要になった情報を残したままにすると、次の処理で古い情報を使ってしまう可能性があります。
今回のように、申込が完了したあとは、保存していた申込情報を削除しておくと安全です。
入力画面を作成する
次に、研修コース申込入力画面を作成します。
trainingEntryForm.jspは、WEB-INF/jspフォルダに作成します。
この画面では、申込ID、確認コード、氏名を入力します。確認コードの入力欄では、inputタグのtype属性にpasswordを指定します。
研修コース申込入力画面を出力するビューの例
ファイル名: trainingEntryForm.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>
<h1>研修コース申込</h1>
<form action="TrainingEntryServlet" method="post">
申込ID:<input type="text" name="entryId"><br>
確認コード:<input type="password" name="passcode"><br>
氏名:<input type="text" name="name"><br>
<input type="submit" value="確認">
</form>
</body>
</html>このJSPファイルでは、formタグのaction属性にTrainingEntryServletを指定しています。
method属性にはpostを指定しているため、確認ボタンをクリックするとTrainingEntryServletのdoPostメソッドが実行されます。
パスワードボックス
確認コードの入力欄では、inputタグのtype属性にpasswordを指定しています。
type属性の値をpasswordにすると、入力した文字が画面上では伏せ字で表示されます。
password指定の特徴
| 項目 | 内容 |
|---|---|
| type属性 | passwordを指定する |
| 表示 | 入力文字が伏せ字で表示される |
| 送信 | name属性に対応した値として送信される |
今回の例では、確認コードの入力欄にname="passcode"を指定しています。
そのため、サーブレット側ではrequest.getParameter("passcode")で取得できます。
入力画面のname属性とサーブレットの対応
trainingEntryForm.jspで指定したname属性は、TrainingEntryServletのdoPostメソッドで値を取得するときに使います。
name属性とgetParameterの対応
| JSP側のname属性 | サーブレット側の取得 |
|---|---|
| entryId | request.getParameter("entryId") |
| name | request.getParameter("name") |
| passcode | request.getParameter("passcode") |
name属性とgetParameterの引数が一致していないと、サーブレット側で値を正しく取得できません。
フォームとサーブレットを連携させるときは、name属性とgetParameterの対応を必ず確認しましょう。
確認画面を作成する
次に、申込確認画面を作成します。
trainingEntryConfirm.jspでは、セッションスコープに保存されたTrainingEntryインスタンスを取得し、申込IDと氏名を表示します。
確認コードは、確認画面には表示しません。
研修コース申込確認画面を出力するビューの例
ファイル名: trainingEntryConfirm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ page import="model.TrainingEntry" %>
<%
TrainingEntry entryUser =
(TrainingEntry) session.getAttribute("entryUser");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>研修コース申込</title>
</head>
<body>
<p>下記の内容で申し込みます</p>
<p>
申込ID:<%= entryUser.getEntryId() %><br>
氏名:<%= entryUser.getName() %><br>
</p>
<a href="TrainingEntryServlet">戻る</a>
<a href="TrainingEntryServlet?action=done">申込</a>
</body>
</html>このJSPでは、session.getAttribute("entryUser")を使って、セッションスコープからTrainingEntryインスタンスを取得しています。
取得したインスタンスはObject型で返されるため、TrainingEntry型にキャストしています。
確認画面でのセッションスコープ利用
確認画面は、入力内容を利用者に確認してもらうための画面です。
この画面では、TrainingEntryServletのdoPostメソッドでセッションスコープに保存したTrainingEntryインスタンスを取得して表示します。
確認画面で行っていること
| 処理 | 内容 |
|---|---|
| page import="model.TrainingEntry" | JSP内でTrainingEntry型を使えるようにする |
| session.getAttribute("entryUser") | セッションスコープから申込情報を取得する |
| (TrainingEntry) | TrainingEntry型へキャストする |
| getEntryId | 申込IDを表示する |
| getName | 氏名を表示する |
JSPでは暗黙オブジェクトsessionをそのまま使えるため、サーブレットのようにrequest.getSessionを記述する必要はありません。
action=doneを送信するリンク
確認画面の申込リンクでは、次のようにURLの末尾にaction=doneを付けています。
TrainingEntryServlet?action=done
このリンクをクリックすると、TrainingEntryServletへGETリクエストが送られます。
action=doneの役割
| 指定 | 内容 |
|---|---|
| TrainingEntryServlet | リクエスト先のサーブレット |
| ? | URLとリクエストパラメータを区切る |
| action=done | 申込実行であることを表すリクエストパラメータ |
TrainingEntryServletのdoGetメソッドでは、request.getParameter("action")でactionの値を取得します。
値がdoneであれば、申込実行のリクエストだと判断します。
完了画面を作成する
最後に、申込完了画面を作成します。
trainingEntryDone.jspでは、申込が完了したことを表示します。
この画面では、すでにTrainingEntryServletで申込処理が行われ、セッションスコープから申込情報も削除されています。
研修コース申込完了画面を出力するビューの例
ファイル名: trainingEntryDone.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>
<a href="TrainingEntryServlet">戻る</a>
</body>
</html>完了画面には、申込が完了したことを知らせるメッセージを表示します。
戻るリンクをクリックすると、TrainingEntryServletへGETリクエストが送られます。このときactionは送信されないため、入力画面へ戻ります。
実行方法
6つのファイルを作成したら、TrainingEntryServletを実行して動作を確認します。
ブラウザから実行する場合は、次のURLへアクセスします。
または、EclipseでTrainingEntryServlet.javaを選択し、サーバーで実行します。
実行の流れ
| 操作 | 表示される画面 |
|---|---|
| TrainingEntryServletへアクセスする | 研修コース申込入力画面 |
| 申込ID、確認コード、氏名を入力して確認をクリックする | 研修コース申込確認画面 |
| 申込をクリックする | 研修コース申込完了画面 |
| 戻るをクリックする | 研修コース申込入力画面 |
動作確認では、最初にTrainingEntryServletへアクセスすることが大切です。
WEB-INF内にあるJSPファイルは、ブラウザから直接リクエストできません。必ずサーブレットからフォワードして表示します。
セッションスコープを使うプログラム実行時の注意点
セッションスコープを使うプログラムでは、以前に保存したインスタンスが残っていることがあります。
そのため、開発途中で何度も実行していると、コードが正しくても、思ったような結果にならない場合があります。
そのようなときは、開いているブラウザをすべて閉じてから、もう一度実行してみましょう。
実行結果がおかしいときの確認
| 状況 | 対応 |
|---|---|
| 以前の入力内容が残っているように見える | ブラウザをすべて閉じて実行し直す |
| 完了後も古い情報が使われる | removeAttributeで削除しているか確認する |
| 確認画面で情報が表示されない | session.setAttributeの属性名とsession.getAttributeの属性名を確認する |
| 最初の画面が出ない | actionの値による分岐を確認する |
セッションスコープはリクエストをまたいでインスタンスを保持できるため便利です。
ただし、開発中は前回の情報が残っていることもあるため、動作確認ではセッションの状態を意識することが大切です。
セッションスコープを使う理由
今回のアプリケーションでセッションスコープを使う理由は、確認画面から申込実行へ進むときに、入力された申込情報を再利用する必要があるからです。
入力画面から確認画面へ進むだけであれば、リクエストスコープでも情報を渡せます。
しかし、確認画面から申込をクリックすると、新しいGETリクエストが発生します。リクエストスコープは前回のレスポンスが返った時点で消えているため、この新しいリクエストでは前回の申込情報を取得できません。
リクエストスコープでは困る点
| 場面 | リクエストスコープの場合 |
|---|---|
| 入力画面から確認画面へ | フォワード中なら利用できる |
| 確認画面から申込実行へ | 新しいリクエストなので利用できない |
| 申込処理で入力内容を使う | 前回の情報を取得できない |
セッションスコープに保存しておけば、確認画面を表示したあとでも、申込実行時に同じTrainingEntryインスタンスを取得できます。
ブラウザの表示例:入力画面

ブラウザの表示例:確認画面

ブラウザの表示例:申込完了画面

完了後にセッションスコープから削除する理由
セッションスコープは、リクエストをまたいでデータを保持できます。
しかし、不要になったデータまで残し続けると、次の処理で古い情報を使ってしまう可能性があります。
今回のアプリケーションでは、申込処理が完了したあと、entryUserをセッションスコープから削除しています。
削除する理由
| 理由 | 内容 |
|---|---|
| 古い申込情報を残さない | 次回の申込で前回の情報を使わないようにする |
| 不要なインスタンスを整理する | セッションスコープに余計な情報を残さない |
| 処理の区切りを明確にする | 申込完了後は申込情報を使い終わったことを示す |
セッションスコープは便利ですが、保存したインスタンスをいつ削除するかも重要です。
今回のように、確認画面と申込実行で使い終わった情報は、完了処理の中でremoveAttributeを使って削除します。
確認したいポイント
セッションスコープを使ったWebアプリケーションでは、ファイル同士のつながりを確認しながら作成することが大切です。
動作確認のポイント
| 確認項目 | 内容 |
|---|---|
| URLパターン | @WebServlet("/TrainingEntryServlet")になっているか |
| 実行URL | http://localhost:8080/study/TrainingEntryServletになっているか |
| JSPの保存場所 | WEB-INF/jspに配置しているか |
| 入力画面のaction属性 | TrainingEntryServletになっているか |
| 入力画面のmethod属性 | postになっているか |
| name属性 | entryId、name、passcodeがdoPostの取得名と一致しているか |
| セッション保存 | session.setAttribute("entryUser", entryUser)で保存しているか |
| セッション取得 | session.getAttribute("entryUser")で取得しているか |
| 申込リンク | TrainingEntryServlet?action=doneになっているか |
| action分岐 | nullとdoneで処理を分けているか |
| セッション削除 | 申込完了後にremoveAttributeで削除しているか |
セッションスコープを使うと、複数の画面をまたいで同じインスタンスを扱えるようになります。
入力、確認、完了のような画面遷移では、どのタイミングで保存し、どのタイミングで取得し、どのタイミングで削除するのかを意識すると、処理の流れがつかみやすくなります。
