Spring Boot 基本

Spring Boot上でセッションIDを確認してみた

セッションを識別するためのIDをセッションIDといい、このセッションIDはクッキーに保存される。また、セッションIDは、別タブや別ウィンドウに新しい画面を表示した場合も、同一のセッションIDが保持される仕組みになっている。

セッションについての説明は、以下のサイトを参照のこと。
https://www.ntt.com/bizon/glossary/j-s/session.html

また、セッションIDとクッキーの関係については、以下のサイトの「Cookieを使用したセッション管理のイメージ」を参照のこと。
https://amg-solution.jp/blog/7061

今回は、セッションIDとクッキーに保存されたセッションIDを確認するようなサンプルプログラムを作成してみたので、共有する。

前提条件

下記記事の実装が完了していること。

IntelliJ IDEA上でGradleを使ってWeb画面のSpring Bootプロジェクトを作成してみたSpring Bootのプロジェクトを新規作成を「IntelliJ IDEA」のメニューから実施しようとしたところ、無料の「Commun...



サンプルプログラムの作成

作成したサンプルプログラムの構成は以下の通り。
サンプルプログラムの構成
なお、上記の赤枠は、前提条件のプログラムから追加/変更したプログラムである。

初期表示画面の内容は以下の通りで、メイン画面への遷移や、新規タブ上や新規ウィンドウ上に画面を開くボタンが配置されている。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>index page</title>
</head>
<body>
これは初期表示画面です。 <br/><br/>
    セッションIDの値 : <span th:text="${sessionId}">sessionIdの値</span><br/>
    クッキーに設定されたセッションIDの値 : 
        <span th:text="${cookieSessionId}">クッキー内のsessionIdの値</span><br/><br/>
    <form method="post" th:action="@{/addSession}">
        <input type="submit" value="セッションの追加" />
    </form><br/><br/>
    <form method="post" th:action="@{/toMain}">
        <input type="submit" value="メイン画面に遷移" />
    </form><br/><br/>
    <form method="GET">
        <input type="button" value="新しいタブを開く" 
            onclick="window.open('/openNewTab', '_blank')" />
    </form><br/><br/>
    <form method="GET">
        <input type="button" value="新しいウィンドウを開く" 
            onclick="window.open('/openNewWindow', '_blank', 'top=100, left=100, height=500, width=1000')" />
    </form><br/><br/>
</body>
</html>
freelance hubを利用して10万件を超える案件情報からJava Spring案件を検索してみたfreelance hubは、レバテックフリーランスやフリエン(furien)を始めとした多くのフリーランスエージェントの案件をまとめて...

また、コントローラクラスの内容は以下の通りで、各画面遷移時に、セッションIDとCookieに設定されたセッションIDを設定するようになっている。

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
public class DemoController {

    /**
     * 初期表示画面に遷移する
     * @param request HttpServletリクエスト
     * @param model Modelオブジェクト
     * @return 初期表示画面
     */
    @GetMapping("/")
    public String index(HttpServletRequest request, Model model){
        // セッションIDと、Cookieに設定されたセッションIDを設定する
        HttpSession session = request.getSession(false);
        model.addAttribute("sessionId"
            , session == null ? "sessionは未作成" : session.getId());
        model.addAttribute("cookieSessionId", getCookieSessionId(request));
        return "index";
    }

    /**
     * セッションを生成し同一画面に遷移する
     * @param request HttpServletリクエスト
     * @param model Modelオブジェクト
     * @return 初期表示画面
     */
    @PostMapping("/addSession")
    public String addSession(HttpServletRequest request, Model model){
        HttpSession session = request.getSession(true);
        model.addAttribute("sessionId"
            , session == null ? "sessionは未作成" : session.getId());
        model.addAttribute("cookieSessionId", getCookieSessionId(request));
        return "index";
    }

    /**
     * メイン画面に遷移する
     * @param request HttpServletリクエスト
     * @param model Modelオブジェクト
     * @return 初期表示画面
     */
    @PostMapping("/toMain")
    public String toMain(HttpServletRequest request, Model model){
        HttpSession session = request.getSession(false);
        model.addAttribute("sessionId"
            , session == null ? "sessionは未作成" : session.getId());
        model.addAttribute("cookieSessionId", getCookieSessionId(request));
        return "main";
    }

    /**
     * 初期表示画面に遷移する
     * @param request HttpServletリクエスト
     * @param model Modelオブジェクト
     * @return 初期表示画面
     */
    @PostMapping("/toIndex")
    public String toIndex(HttpServletRequest request, Model model){
        HttpSession session = request.getSession(false);
        model.addAttribute("sessionId"
            , session == null ? "sessionは未作成" : session.getId());
        model.addAttribute("cookieSessionId", getCookieSessionId(request));
        return "index";
    }

    /**
     * 新しいタブを開く
     * @param request HttpServletリクエスト
     * @param model Modelオブジェクト
     * @return 新規タブ画面へのパス
     */
    @GetMapping("/openNewTab")
    public String openNewTab(HttpServletRequest request, Model model){
        HttpSession session = request.getSession(false);
        model.addAttribute("sessionId"
            , session == null ? "sessionは未作成" : session.getId());
        model.addAttribute("cookieSessionId", getCookieSessionId(request));
        return "new_tab";
    }

    /**
     * 新しい画面を開く
     * @param request HttpServletリクエスト
     * @param model Modelオブジェクト
     * @return 新規オープン画面へのパス
     */
    @GetMapping("/openNewWindow")
    public String openNewWindow(HttpServletRequest request, Model model){
        HttpSession session = request.getSession(false);
        model.addAttribute("sessionId"
            , session == null ? "sessionは未作成" : session.getId());
        model.addAttribute("cookieSessionId", getCookieSessionId(request));
        return "new_window";
    }

    /**
     * CookieのセッションIDを取得する
     * @param request HttpServletリクエスト
     * @return CookieのセッションID
     */
    private String getCookieSessionId(HttpServletRequest request){
        if(request == null || request.getCookies() == null){
            return "CookieのセッションIDは未設定";
        }
        Cookie cookie[] = request.getCookies();
        for (int i = 0 ; i < cookie.length ; i++) {
            if ("JSESSIONID".equals(cookie[i].getName())) {
                return cookie[i].getValue();
            }
        }
        return "CookieのセッションIDは未設定";
    }
}
「MiniTool Partition Wizard」はパーティション分割・統合・バックアップ・チェックを直感的に行える便利ツールだったハードディスクの記憶領域を論理的に分割し、分割された個々の領域のことを、パーティションといいます。 例えば、以下の図の場合、C/D...

さらに、メイン画面の内容は、以下の通り。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>main page</title>
</head>
<body>
メイン画面に遷移しました。<br/><br/>
セッションIDの値 : <span th:text="${sessionId}">sessionIdの値</span><br/>
クッキーに設定されたセッションIDの値 : 
    <span th:text="${cookieSessionId}">クッキー内のsessionIdの値</span><br/><br/>
<form method="post" th:action="@{/toIndex}">
    <input type="submit" value="戻る" />
</form>
</body>
</html>

また、新しいタブを開いて表示される新規タブ画面の内容は、以下の通り。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>new tab</title>
</head>
<body>
新しいタブを開きました。 <br/><br/>
セッションIDの値 : <span th:text="${sessionId}">sessionIdの値</span><br/>
クッキーに設定されたセッションIDの値 : 
    <span th:text="${cookieSessionId}">クッキー内のsessionIdの値</span><br/><br/>
</body>
</html>

さらに、新しいウィンドウを開いて表示される新規ウィンドウ画面の内容は、以下の通り。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>new window</title>
</head>
<body>
新しい画面を開きました。 <br/><br/>
セッションIDの値 : <span th:text="${sessionId}">sessionIdの値</span><br/>
クッキーに設定されたセッションIDの値 : 
    <span th:text="${cookieSessionId}">クッキー内のsessionIdの値</span><br/><br/>
</body>
</html>

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-sessionid/demo



サンプルプログラムの実行結果

サンプルプログラムの実行結果は、以下の通り。

1) Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスすると、以下のように、初期表示画面が表示されることが確認できるので、「セッションの追加」ボタンを押下する。
サンプルプログラムの実行結果_1

2) 以下のように、セッションIDが発番され、クッキーへのセッションIDはまだ設定されていないことが確認できる。ここで「セッションの追加」ボタンを再度押下する。
サンプルプログラムの実行結果_2

3) 以下のように、クッキーへのセッションIDも設定されたことが確認できる。ここで「メイン画面に遷移」ボタンを押下する。
サンプルプログラムの実行結果_3

4) 以下のように、前画面と同一のセッションIDが設定されていることが確認できる。ここで「戻る」ボタンを押下する。
サンプルプログラムの実行結果_4

5) 以下のように、前画面と同一のセッションIDが設定されていることが確認できる。ここで「新しいタブを開く」ボタンを押下する。
サンプルプログラムの実行結果_5

6) 以下のように、新しいタブ上に新規画面が開き、前画面と同一のセッションIDが設定されていることが確認できる。
サンプルプログラムの実行結果_6

7) 以下のように、初期表示画面で「新しいウィンドウを開く」ボタンを押下すると、新しいウィンドウ上に新規画面が開き、前画面と同一のセッションIDが設定されていることが確認できる。
サンプルプログラムの実行結果_7_1

サンプルプログラムの実行結果_7_2

要点まとめ

  • セッションを識別するためのIDをセッションIDといい、このセッションIDはクッキーに保存される。
  • セッションIDは、別タブや別ウィンドウに新しい画面を表示した場合も、同一のセッションIDが保持される仕組みになっている。