Spring MVCのセッションオブジェクト管理の調査

Dev/Java/Spring Boot
Java
Spring Boot
Spring Session
Redis

更新日時 : 2021/03/13 11:04
投稿日時 : 2021/03/13 10:59

概要

厳密にはSpring Sessionだが、業務でSpring MVC+Redisを使用したWebアプリを開発していて、Controllerクラスのセッションに関する動作を検証した。

  • Spring MVC+Redisを使用
  • SessionAttributesアノテーションでセッションオブジェクトを管理
  • 特定動作完了後にセッション中のオブジェクトを削除またはセッションを破棄する

用意したクラス

  • UserController
    • UserFormオブジェクトをSessionで管理する
    • @SessionAttributesを付与
  • UserNextController
    • UserFormオブジェクトをSessionで管理するが、値設定はしない
    • @SessionAttributesを付与
  • UserSessionCompleteController
    • @SessionAttributesを付与しない

実行するメソッド

  • org.springframework.web.bind.support.SessionStatus.setComplete
    • Session中のオブジェクトを明示的に削除する
  • javax.servlet.http.HttpSession.invalidate
    • Sessionを明示的に破棄する

application.propertiesの設定値

デフォルトのまま

キー デフォルト値 説明
spring.session.redis.configure-action notify-keyspace-events ユーザー定義の ConfigureRedisAction Bean が存在しない場合に適用する構成アクション。
spring.session.redis.flush-mode on-save セッションフラッシュモード。セッションの変更をセッションストアに書き込むタイミングを決定します。
spring.session.redis.namespace spring:session セッションの保存に使用されるキーの名前空間。
spring.session.redis.save-mode on-set-attribute セッション保存モード。セッションの変更を追跡し、セッションストアに保存する方法を決定します。

アプリケーションプロパティ設定一覧より引用

UserController

  • 同じController内での画面制御結果

セッションオブジェクトの削除

setCompleteパターン 1 2 3 4
画面遷移 /user/input /user/detail /user/complete /user/detail
画面説明 入力フォーム 入力値表示 同ControllerでsessionState.setComplete 入力値表示
セッションID X X X X
formの値(初期をAとする) A A A formオブジェクトが取得できない
  • セッションIDは変更されない
  • セッションオブジェクトであるUserFormが削除され、HttpSessionRequiredExceptionが発生する

セッションの削除

invalidateパターン 1 2 3 4
画面遷移 /user/input /user/detail /user/next/discard /user/detail
画面説明 入力フォーム 入力値表示 別Controllerでsession.invalidate 入力値表示
セッションID X X X Y
formの値(初期をAとする) A A A A
  • セッションIDが変更される
  • セッションオブジェクトはID変更後も保持される

UserNextController

  • 同じセッションオブジェクトを@SessionAttributesに設定した別クラスでの画面制御結果
  • 結果はUserControllerと変わらず

セッションオブジェクトの削除

setCompleteパターン 1 2 3 4
画面遷移 /user/input /user/detail /user/next/complete /user/detail
画面説明 入力フォーム 入力値表示 同ControllerでsessionState.setComplete 入力値表示
セッションID X X X X
formの値(初期をAとする) A A A formオブジェクトが取得できない
  • セッションIDは変更されない
  • セッションオブジェクトであるUserFormが削除され、HttpSessionRequiredExceptionが発生する

セッションの削除

invalidateパターン 1 2 3 4
画面遷移 /user/input /user/detail /user/next/discard /user/detail
画面説明 入力フォーム 入力値表示 別Controllerでsession.invalidate 入力値表示
セッションID X X X Y
formの値(初期をAとする) A A A A
  • セッションIDが変更される
  • セッションオブジェクトはID変更後も保持される

UserSessionCompleteController

  • @SessionAttributesに設定しない別クラスでの画面制御結果
  • 同クラス内でsessionCompleteしてもセッションオブジェクトは削除されない
  • 同クラス内でinvalidateすると、セッションID変更とオブジェクトも削除される
    • 上記結果と異なり、オブジェクトは新しいセッションに引き継がれない

セッションオブジェクトの削除

setCompleteパターン 1 2 3 4
画面遷移 /user/input /user/detail /user/session/complete /user/detail
画面説明 入力フォーム 入力値表示 別ControllerでsessionState.setComplete 入力値表示
セッションID X X X X
formの値(初期をAとする) A A formオブジェクトが取得できない A
画面説明 入力フォーム 入力値表示 別ControllerでsessionState.setComplete 入力値表示
  • セッションIDは変更されない
  • セッションオブジェクトも削除されず、残ったまま

セッションの削除

invalidateパターン 1 2 3 4
画面遷移 /user/input /user/detail /user/next/discard /user/detail
画面説明 入力フォーム 入力値表示 別Controllerでsession.invalidate 入力値表示
セッションID X X X Y
formの値(初期をAとする) A A formオブジェクトが取得できない formオブジェクトが取得できない
  • セッションIDが変更される
  • セッションオブジェクトも削除される
    • HttpSessionRequiredExceptionが発生する

まとめ

  1. @SessionAttributesを付与したクラス内でHttpSession.invalidateメソッドを呼び出してもセッション中のオブジェクトは削除されず、sessionIdが変更されてオブジェクトは残ったままとなる
  2. @SessionAttributesを付与したクラス内でSessionStatus.setCompleteを実行すると、削除される。
  3. @SessionAttributesを付与していないクラスでHttpSession.invalidateを実行すると、セッションIDの書き換えとともにオブジェクトも削除される

個人的には1.と3.について実装でハマる可能性があるかなと感じた。本来Spring MVC利用していて、HttpSessionを直接操作すること自体は減らす必要があるが、もし必要になった場合は参考にしてほしい。

サンプルコード

https://github.com/vagivagi/demo-redis