サーブレット&JSPの基本|セッションスコープの使い方

レスポンス後もデータを残せる。セッションスコープでリクエストをまたいだ情報共有を身につけよう

リクエストスコープを使うと、サーブレットで作成したインスタンスをJSPへ渡せます。

たとえば、サーブレットで処理結果を作成し、そのインスタンスをリクエストスコープに保存してからJSPへフォワードすれば、JSP側でそのインスタンスを取得して画面に表示できます。

しかし、リクエストスコープには大きな特徴があります。

それは、1回のリクエストが終わると保存したインスタンスも利用できなくなるという点です。レスポンスがブラウザへ返されると、そのリクエストで使っていたリクエストスコープの内容は残りません。

そのため、リクエストをまたいで同じインスタンスを使いたい場合、リクエストスコープでは対応できません。

そこで登場するのがセッションスコープです。

セッションスコープを使うと、レスポンスが返されたあともインスタンスを残しておくことができます。次のリクエストでも同じインスタンスを利用できるため、ログイン中のユーザー情報や、複数画面にまたがって使いたい情報を扱うときに役立ちます。

この記事では、セッションスコープの特徴、HttpSessionの取得方法、setAttributeによる保存、getAttributeによる取得、removeAttributeによる削除、そしてJSPでセッションスコープを利用する方法を解説します。

リクエストスコープではリクエストをまたげない

リクエストスコープは、1回のリクエストの中でデータを共有するためのスコープです。

サーブレットからJSPへフォワードするときには便利ですが、レスポンスが返されたあとは保存したインスタンスを利用できません。

たとえば、学習者情報をリクエストスコープに保存した場合、そのリクエスト内でフォワードされたJSPでは取得できます。しかし、次に別の画面へアクセスしたときには、前回のリクエストスコープの内容は残っていません。

リクエストスコープの特徴

項目内容
保存できる期間1回のリクエストが終わるまで
レスポンス後保存したインスタンスは利用できない
次回リクエスト前回保存したインスタンスは取得できない
向いている用途サーブレットからJSPへ一時的に処理結果を渡す

この性質は、入力結果を1回だけ表示するような処理には向いています。

しかし、複数のリクエストにまたがって情報を使いたい場合には不向きです。

セッションスコープとは

セッションスコープは、リクエストをまたいでインスタンスを保存できるスコープです。

リクエストスコープに保存したインスタンスはレスポンス後に消えますが、セッションスコープに保存したインスタンスは、レスポンス後も残すことができます。

そのため、次回以降のリクエストでも同じインスタンスを取得して利用できます。

セッションスコープの特徴

特徴内容
リクエストをまたげるレスポンス後もインスタンスを残せる
有効期間を決められる保存したインスタンスをどのくらい使うかを開発者が考えられる
複数画面で利用しやすい画面を移動しても同じ情報を使える
明示的に削除できる不要になったインスタンスをremoveAttributeで削除できる

セッションスコープを使うと、1回の画面表示だけでなく、利用者の一連の操作の中で同じ情報を使えるようになります。

たとえば、ログインした学習者の名前や受講コースを保存しておけば、別の画面へ移動しても、その情報を表示できます。

図1:リクエストをまたいで使えるセッションスコープ

この図から分かること

セッションスコープは、1回のリクエストだけで終わらず、次のリクエストでも利用できる保存領域です。

LoginServletで学習者情報を表すLearningUserインスタンスを作成し、セッションスコープに保存しておけば、別のリクエストで表示されるmyPage.jspでも同じインスタンスを取得できます。

リクエストスコープはレスポンスが返ると使えなくなりますが、セッションスコープはレスポンス後もインスタンスを残せる点が大きな違いです。

セッションスコープの正体

セッションスコープの正体は、HttpSessionインスタンスです。

リクエストスコープではHttpServletRequestインスタンスを使いました。リクエストスコープを操作するときは、request.setAttributeやrequest.getAttributeを使いました。

一方、セッションスコープではHttpSessionインスタンスを使います。

サーブレットクラスでHttpSessionインスタンスを取得するには、HttpServletRequestインスタンスのgetSessionを使います。

セッションスコープを操作する流れ

順番内容
1request.getSessionでHttpSessionインスタンスを取得する
2session.setAttributeでインスタンスを保存する
3session.getAttributeでインスタンスを取得する
4不要になったらsession.removeAttributeで削除する

セッションスコープを使うには、jakarta.servlet.http.HttpSessionをインポートする必要があります。

サーブレットでは、まずrequestからsessionを取得し、そのsessionに対して保存や取得を行う、と考えると分かりやすくなります。

HttpSessionを取得する

サーブレットクラスでセッションスコープを使うには、最初にHttpSessionインスタンスを取得します。

取得にはrequest.getSessionを使います。

HttpSessionの取得

処理内容
request.getSessionHttpSessionインスタンスを取得する
HttpSession session取得したセッションを扱う変数

リクエストスコープではrequestそのものを使いましたが、セッションスコープではrequestからsessionを取り出して使います。

つまり、セッションスコープを操作する準備として、まずHttpSession session = request.getSession();という形を作ります。

セッションスコープにインスタンスを保存する

セッションスコープにインスタンスを保存するには、session.setAttributeを使います。

使い方は、リクエストスコープのsetAttributeとよく似ています。

setAttributeの基本

引数内容
第1引数属性名をString型で指定する
第2引数保存するインスタンスを指定する

属性名は、セッションスコープ内でインスタンスを管理するための名前です。

あとで取得するときは、この属性名を指定します。

保存時の注意点

注意点内容
属性名は大文字と小文字を区別するloginUserとLoginUserは別の名前として扱われる
同じ属性名で保存すると上書きされる後から保存したインスタンスに置き換わる
第2引数はObject型さまざまなクラスのインスタンスを保存できる

たとえば、LearningUserインスタンスをloginUserという属性名で保存した場合、取得するときもloginUserという属性名を使います。

属性名が少しでも違うと取得できないため、保存側と取得側で名前をそろえることが大切です。

セッションスコープからインスタンスを取得する

セッションスコープに保存したインスタンスを取得するには、session.getAttributeを使います。

getAttributeの引数には、保存時に指定した属性名を指定します。

ただし、getAttributeの戻り値はObject型です。そのため、取得したインスタンスを元の型として扱うにはキャストが必要です。

getAttributeの基本

項目内容
引数取得したいインスタンスの属性名
戻り値Object型
必要な処理元の型へのキャスト
属性名が存在しない場合nullが返される

LearningUser型のインスタンスを取得したい場合は、Object型として返されたものをLearningUser型にキャストします。

この考え方は、リクエストスコープのgetAttributeと同じです。

セッションスコープからインスタンスを削除する

セッションスコープに保存したインスタンスは、removeAttributeで削除できます。

セッションスコープはレスポンス後もインスタンスを残せるため、不要になったインスタンスをそのまま残し続けないように、必要に応じて削除します。

removeAttributeの基本

項目内容
使用するメソッドsession.removeAttribute
引数削除するインスタンスの属性名
属性名大文字と小文字を区別する

たとえば、loginUserという属性名で保存したインスタンスを削除する場合は、loginUserを指定して削除します。

保存、取得、削除の3つをセットで覚えると、セッションスコープの基本操作が理解しやすくなります。

図2:HttpSessionを使った保存・取得・削除

この図から分かること

セッションスコープを操作するには、HttpSessionインスタンスを使います。

サーブレットでは、まずrequest.getSessionでHttpSessionインスタンスを取得します。その後、session.setAttributeでインスタンスを保存し、session.getAttributeで取得できます。

不要になったインスタンスはsession.removeAttributeで削除できます。リクエストスコープと同じようにsetAttributeとgetAttributeを使いますが、操作する対象がrequestではなくsessionになる点に注意しましょう。

サーブレットクラスでセッションスコープを利用する例

ここでは、学習者情報を表すLearningUserインスタンスをセッションスコープに保存し、取得し、削除する例を見てみましょう。

LearningUserは、名前、受講コース、学習時間を持つJavaBeansとして作成済みであるとします。

サーブレットクラスでセッションスコープを利用する例

package servlet;

import java.io.IOException;

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.LearningUser;

@WebServlet("/SessionUserServlet")
public class SessionUserServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException, IOException {

        // セッションスコープに保存するインスタンスの生成
        LearningUser user = new LearningUser();
        user.setName("青山 直人");
        user.setCourse("サーブレット&JSPの基本);
        user.setStudyMinutes(90);

        // HttpSessionインスタンスの取得
        HttpSession session = request.getSession();

        // セッションスコープにインスタンスを保存
        session.setAttribute("loginUser", user);

        // セッションスコープからインスタンスを取得
        LearningUser savedUser =
                (LearningUser) session.getAttribute("loginUser");

        // セッションスコープからインスタンスを削除
        session.removeAttribute("loginUser");
    }
}

このサーブレットでは、LearningUserインスタンスを作成し、loginUserという属性名でセッションスコープに保存しています。

その後、同じloginUserという属性名を使ってセッションスコープから取得しています。

最後に、removeAttributeを使ってloginUserを削除しています。

SessionUserServlet.javaのポイント

SessionUserServlet.javaでは、セッションスコープの基本操作を順番に確認できます。

処理の流れ

順番処理内容
1LearningUserインスタンスを生成するセッションスコープに保存するデータを用意する
2request.getSessionを実行するHttpSessionインスタンスを取得する
3session.setAttributeを実行するloginUserという属性名で保存する
4session.getAttributeを実行するloginUserという属性名で取得する
5session.removeAttributeを実行するloginUserをセッションスコープから削除する

セッションスコープでは、requestではなくsessionに対してsetAttributeやgetAttributeを使います。

リクエストスコープの操作と似ていますが、保存先が違うため、どちらのスコープを使っているのかを意識することが大切です。

requestとsessionの使い分け

リクエストスコープとセッションスコープは、どちらもsetAttributeとgetAttributeを使ってインスタンスを保存、取得できます。

しかし、操作する対象が違います。

requestとsessionの違い

スコープ操作に使うもの保存期間
リクエストスコープHttpServletRequestのrequest1回のリクエストが終わるまで
セッションスコープHttpSessionのsessionレスポンス後も残せる

リクエストスコープは、一時的にJSPへデータを渡すときに向いています。

セッションスコープは、次のリクエストでも利用したいデータを保存するときに向いています。

たとえば、結果画面だけで表示する一時的なメッセージならリクエストスコープが向いています。一方、ログイン中のユーザー情報のように、複数画面で使いたい情報はセッションスコープが向いています。

セッションスコープでも属性名が重要

セッションスコープでも、属性名はとても重要です。

保存するときに指定した属性名と、取得するときに指定した属性名が一致していないと、目的のインスタンスを取得できません。

属性名の例

操作記述の考え方
保存loginUserという属性名でLearningUserを保存する
取得loginUserという属性名でLearningUserを取得する
削除loginUserという属性名でLearningUserを削除する

属性名は大文字と小文字を区別します。

loginUser、LoginUser、loginuserは、それぞれ別の属性名として扱われます。

セッションスコープはリクエストをまたいで使えるため、属性名を間違えると別の画面でも取得できなくなります。名前は分かりやすく、保存側と取得側で統一しましょう。

JSPファイルでセッションスコープを利用する

JSPファイルでも、セッションスコープを利用できます。

サーブレットでは、request.getSessionを使ってHttpSessionインスタンスを取得しました。

しかし、JSPファイルでは、暗黙オブジェクトとしてsessionがあらかじめ用意されています。そのため、JSPの中でわざわざgetSessionを使う必要はありません。

JSPでのセッションスコープ操作

操作使用するもの
セッションスコープから取得するsession.getAttribute
セッションスコープへ保存するsession.setAttribute
セッションスコープから削除するsession.removeAttribute

JSPでよく使うのは、セッションスコープに保存されているJavaBeansインスタンスを取得し、そのプロパティを画面に出力する使い方です。

JSPファイルでセッションスコープから取得して表示する例

ここでは、セッションスコープに保存されているLearningUserインスタンスをJSPで取得し、名前、受講コース、学習時間を表示します。

JSPでLearningUser型を使うため、pageディレクティブでmodel.LearningUserをインポートします。

JSPファイルでもセッションスコープを利用する例

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
<%@ page import="model.LearningUser" %>

<%
    // セッションスコープからインスタンスを取得
    LearningUser user =
            (LearningUser) session.getAttribute("loginUser");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>学習者情報</title>
</head>
<body>
<h1>学習者情報</h1>
<p>
名前:<%= user.getName() %><br>
受講コース:<%= user.getCourse() %><br>
本日の学習時間:<%= user.getStudyMinutes() %>分
</p>
</body>
</html>

このJSPでは、session.getAttribute("loginUser")を使って、セッションスコープからLearningUserインスタンスを取得しています。

getAttributeの戻り値はObject型なので、LearningUser型にキャストしています。

その後、getterを使って、name、course、studyMinutesの値を画面に出力しています。

JSPでsessionをそのまま使える理由

JSPには、よく使うオブジェクトがあらかじめ用意されています。

このようなオブジェクトを暗黙オブジェクトと呼びます。

sessionも暗黙オブジェクトの1つです。そのため、JSPファイルの中では、自分でHttpSession sessionを宣言しなくても、session.getAttributeを使えます。

サーブレットとJSPでの違い

場所セッションスコープを使う方法
サーブレットrequest.getSessionでHttpSessionを取得してから使う
JSP暗黙オブジェクトsessionをそのまま使う

サーブレットでは、まずHttpSessionを取得する必要があります。

JSPでは、sessionがあらかじめ用意されているため、そのままセッションスコープを操作できます。

図3:JSPでsession暗黙オブジェクトを使う

この図から分かること

JSPでは、暗黙オブジェクトsessionを使ってセッションスコープを操作できます。

サーブレットのようにrequest.getSessionを実行しなくても、session.getAttributeでセッションスコープからインスタンスを取得できます。

ただし、取得したインスタンスはObject型として返されるため、LearningUser型にキャストします。また、JSPでLearningUser型を使うためには、pageディレクティブでmodel.LearningUserをインポートします。

セッションスコープとJavaBeans

セッションスコープには、JavaBeansインスタンスを保存することができます。

今回の例では、LearningUserというJavaBeansをセッションスコープに保存しました。

JavaBeansには、関連する情報をまとめて持たせることができます。名前、受講コース、学習時間のような複数の値を1つのインスタンスにまとめられるため、セッションスコープで扱いやすくなります。

セッションスコープにJavaBeansを保存する利点

利点内容
複数の情報をまとめられる名前、コース、学習時間などを1つにできる
JSPで表示しやすいgetterを使ってプロパティを出力できる
リクエストをまたいで使える別画面でも同じインスタンスを取得できる
管理しやすい属性名1つで関連情報をまとめて扱える

サーブレットでJavaBeansを作成し、セッションスコープに保存します。

JSPではセッションスコープからJavaBeansを取得し、getterでプロパティの値を取り出して表示します。

セッションスコープで確認したいこと

セッションスコープを使うときは、次の点を確認しましょう。

確認項目内容
HttpSessionをインポートしているかサーブレットではjakarta.servlet.http.HttpSessionが必要
request.getSessionを使っているかサーブレットでsessionを取得する
保存はsession.setAttributeかrequestではなくsessionに保存する
取得はsession.getAttributeかセッションスコープから取り出す
削除はsession.removeAttributeか不要なインスタンスを削除する
属性名は一致しているか保存、取得、削除で同じ属性名を使う
キャストしているかgetAttributeの戻り値はObject型
JSPでimportしているかJavaBeansの型を使うにはインポートが必要
JSPではsessionをそのまま使っているか暗黙オブジェクトsessionを利用できる

リクエストスコープとセッションスコープは、setAttributeとgetAttributeを使う点では似ています。

しかし、保存先がrequestなのかsessionなのか、保存したインスタンスがレスポンス後も残るのか、という点が大きく異なります。

リクエストスコープとセッションスコープの違い

リクエストスコープとセッションスコープは、どちらもインスタンスを保存できます。

ただし、保存したインスタンスを利用できる期間が違います。

2つのスコープの違い

比較項目リクエストスコープセッションスコープ
操作に使うものHttpServletRequestHttpSession
サーブレットでの変数requestsession
保存方法request.setAttributesession.setAttribute
取得方法request.getAttributesession.getAttribute
利用できる期間レスポンスが返されるまでレスポンス後も残せる
リクエストをまたげるかまたげないまたげる
主な用途1回だけ表示する処理結果複数画面で使う情報

リクエストスコープは、サーブレットからJSPへ一時的に値を渡すときに向いています。

セッションスコープは、リクエストをまたいで同じ情報を使いたいときに向いています。

セッションスコープを使う場面

セッションスコープは、レスポンス後もインスタンスを残せるため、複数のリクエストで使いたい情報に向いています。

たとえば、ある画面で学習者情報を保存し、次の画面でも同じ学習者名を表示したい場合に使えます。

セッションスコープが向いている場面

場面理由
ログイン中の利用者情報を持ちたい画面を移動しても同じ利用者として扱いたい
複数画面で同じ情報を表示したいレスポンス後も情報を残せる
一連の操作の中で同じインスタンスを使いたいリクエストをまたいで共有できる

セッションスコープを使うと、アプリケーションで扱える情報の幅が広がります。

リクエストごとに消えてしまっては困る情報を扱うとき、セッションスコープが重要になります。

不要になったインスタンスは削除する

セッションスコープはレスポンス後もインスタンスを残せるため、とても便利です。

しかし、不要になったインスタンスを残したままにすると、意図しない情報が次の処理で使われる可能性があります。

そのため、必要がなくなったインスタンスはremoveAttributeで削除します。

削除の考え方

状況対応
もう使わない情報があるremoveAttributeで削除する
保存し直したい情報があるsetAttributeで同じ属性名に上書きできる
取得できない場合属性名の間違いや削除済みでないか確認する

セッションスコープはリクエストスコープより長く残る分、保存した情報をいつまで使うのかを意識することが大切です。

セッションスコープの基本として押さえること

セッションスコープは、リクエストをまたいでインスタンスを利用するためのスコープです。

リクエストスコープではレスポンス後にインスタンスが消えますが、セッションスコープではレスポンス後もインスタンスを残せます。

サーブレットではrequest.getSessionでHttpSessionを取得し、session.setAttribute、session.getAttribute、session.removeAttributeを使って操作します。

JSPでは暗黙オブジェクトsessionを使えるため、getSessionを使わずにsession.getAttributeでインスタンスを取得できます。

操作サーブレットで使うものJSPで使うもの
セッションの取得request.getSession暗黙オブジェクトsessionをそのまま使う
保存session.setAttributesession.setAttribute
取得session.getAttributesession.getAttribute
削除session.removeAttributesession.removeAttribute

リクエストスコープでできなかった、リクエストをまたいだインスタンスの共有を実現できるのがセッションスコープです。

複数画面で同じ情報を使う必要がある場合は、セッションスコープを利用する流れを押さえておきましょう。