☕
[Servlet]Session機能の実装
◆はじめに
SessionのIdを取得します。
Session機能で、セッションがリセットされるまでパラメータが保持されます。
◆Sessionとは
簡単に言えば、
「セッションが続いている間は、パラメータが保持される仕組み」です。
以下の概略図を作りましたのでご覧ください。
セッションに対して、ユニークなキーであるセッションIDが与えられています。
なので、ページを更新しようが、ブラウザを閉じても、
パラメータを保持することが可能です。
このように、セッションで状態を保持することができるようになることで、
情報を更新する場合など、毎回全ての情報を送る必要がないので手間が省けます。
これを「ステートフル」といいます。
セッション機能を利用すれば、
例えば、ショッピングサイトのカートや、ページの訪問回数のカウントなど
ステートフルなWebアプリケーションを作成できます。
◆前提/環境など
本記事は、以下の記事の「InputFunction」プロジェクトをベースに作成しています。
Echo機能のServletの処理時間を計測するFilterを実装しています。
以下の記事の内容を踏まえた前提で、記事は書いていますのでご了承ください。
仕様は以下です。
<Echo機能> ・文字列を入力し、送信ボタンを押すと、送信した文字列が画面に表示される。
<Validation機能> ・送信された文字列が空欄の場合は,「この項目は必須入力です。」と文字列が表示される。
<TimeFiletr機能(Listener)> ・Servletの処理時間を計測し、コンソールに表示
※本記事では、 eclipseは以下のバージョンでの画像を使用しています。
日本語化はしていません。
他のversionでの動作は確認しておりません。
◆手順
それでは、先ほど紹介した「InputFunction」プロジェクトに対して、
Session機能を追加していきます。
変更箇所と追加箇所をメインに記載しています。
①変更を加えるファイル
今回は、「EchoServlet.java」に変更を加えます。
それ以外のファイルのコードや追加しているライブラリーに関しては、特に変更はありません。
ディレクトリ構造は以下です。
②Session機能のコード
・以下のコードを、「EchoServlet.java」に記述
EchoServlet.java
package input;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
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 javax.servlet.http.HttpSession;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
//URLを定義するアノテーション
@WebServlet(urlPatterns = {"/echo"})
//Validation機能を持たせたEchoサーブレットクラス
public class EchoServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
//画面からPostされた場合に起動するメインとなるメソッド
@Override
protected void doPost(HttpServletRequest request , HttpServletResponse response)throws ServletException,
IOException {
//取得文字のエンコード設定(文字化け防止)
request.setCharacterEncoding("UTF-8");
//セッションの取得
HttpSession session = request.getSession();
//Validation機能
//テキストボックスのtextを保持したFormの作成
TextForm SetForm = toSetForm(request);
//toValidationFormをバリデーションに通す。
//引っかかった場合はrequestにvalidationMessageをセットする
setValidationAttribute(session,SetForm);
//Echo機能
//Echoメッセージのセット
if(session.getAttribute("validationMessage") == null) {
//バリデーションメッセージがrequestに付与されていない場合、
//Formに保持していたtextをrequestにEcho用に付与する
String EchoMessage = SetForm.getTextMessage();
//取得したセッションのmessageに対してセットする
session.setAttribute("message",EchoMessage);
}
//Echo保持されている時の、バリデーションが働いた時,EchoMessageは初期化
if(session.getAttribute("validationMessage") != null) {
//取得したセッションのmessageに対してセットする
session.setAttribute("message",null);
}
//セッションIDの取得
String session_id = session.getId();
//コンソールに出力
System.out.println("セッションID:" + session_id );
System.out.println("validationMessage<session>):"+session.getAttribute("validationMessage"));
System.out.println("message<session>):"+session.getAttribute("message"));
// //RequestDispatcher
RequestDispatcher dispatcher = request.getRequestDispatcher("echo.jsp");
dispatcher.forward(request, response);
}
//「セッションのリセット」のリクエストパラメータが渡された場合が押された場合、セッションを無効にする
@Override
protected void doGet(HttpServletRequest request , HttpServletResponse response) throws ServletException,IOException {
Map<String , String[]> parameterMap = request.getParameterMap();
if(parameterMap.containsKey("reset") == true) {
//セッションの取得
HttpSession session = request.getSession();
//セッションを無効にする
session.invalidate();
}
RequestDispatcher dispatcher = request.getRequestDispatcher("echo.jsp");
dispatcher.forward(request,response);
}
//テキストを保持したFormを作成するメソッド
private TextForm toSetForm(HttpServletRequest request) {
//バリデーションに通すためのフォームのインスタンス作成
TextForm SetForm = new TextForm();
//テキストボックスの文字列を取得
String text = request.getParameter("m");
//テキストボックスが空欄ではない場合
if(text.isEmpty() == false) {
//テキストを保持したFormを返す(今回は実装してないがNull以外のバリデーション機能もあるため)
SetForm.setTextMessage(text);
}
return SetForm;
}
//バリデーション用のメソッド
private void setValidationAttribute(HttpSession session, TextForm toValidationForm) {
//toValidationFormに対してバリデーションを実行
Map<String,List<String>> validationMessage = validate(session,toValidationForm);
//バリデーションメッセージがセットされている場合、requestにバリデーションメッセージを付与
if(validationMessage.isEmpty() == false) {
session.setAttribute("validationMessage", validationMessage);
return;
}
//Sessionで保持されていたバリデーションメッセージの初期化
if(validationMessage.isEmpty() == true) {
session.setAttribute("validationMessage", null);
return;
}
}
//validate
private Map<String , List<String>> validate(HttpSession session,TextForm toSetForm){
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
Set<ConstraintViolation<TextForm>> validationResult = validator.validate(toSetForm);
Map<String , List<String>> ret = new HashMap<String , List<String>>();
for(ConstraintViolation<TextForm> violation : validationResult) {
String propertyPath = violation.getPropertyPath().toString();
List<String> messages = ret.get(propertyPath);
if(messages == null) {
messages = new ArrayList<String>();
ret.put(propertyPath, messages);
}
messages.add(violation.getMessage());
}
return ret;
}
}
③動作チェック
・Tomcatなどアプリケーションサーバーを起動
・実装後に以下のURLにアクセス
以下の画面が表示されます。
それでは、以下の操作を行って、
Session機能について確認していきましょう。
(1)セッションの取得
・テキストボックスに「セッションの保持」と入力
・送信ボタンを押す
・コンソールを確認
すると、取得したSessionIdが表示されていることが確認できます。
(2)セッションの保持
・ブラウザを更新する。または、ブラウザを閉じて再度アクセスする
・コンソールを確認
すると、同じSessionIdで、保持されたテキストが表示されていることを確認できます。
(3)セッションのリセット
・「セッションのリセット」を押す
すると、保持されたテキストが消えます。
また、この時にSessionIdは破棄されています。
(4)セッションの再取得
・テキストボックスに「セッションの再取得」と入力
・送信ボタンを押す
すると、初めとは別のSessionIdが取得されたことを確認できます。
◆さいごに
以上です。いかがだったでしょうか。
Sessionの実装はできたでしょうか。
今回のポイントです。
①request.getSession()を使用して、セッションを取得する
②セッションは破棄されるまで同じなので、パラメータが保持される
③セッションをリセットすると新しいセッションIDになる
コードに関しての詳しい説明に関しては、
あまり書いていません。少し、コード内にコメントはつけてます。
あとは、他の参考に載せている書籍やサイトなど調べてみてください。
最後まで、ご覧いただきありがとうございました。
◆参考
本記事は、以下の書籍を大いに参考にしています。
より詳しく知りたい方は、どうぞ。
・関連記事、その他
Discussion