0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

📘 Vol.11.2.4「セッションとパラメータの使い分けと設計ポイント」

Last updated at Posted at 2025-05-26

本記事では、Struts2ベースのWebアプリケーションにおける「セッションとパラメータの使い分け」について、実装例を交えて整理します。

画面遷移を伴うWebアプリケーションにおいて、「どの情報をセッションで保持し、どの情報をパラメータで渡すか」は、設計段階での重要な検討ポイントです。特に複数画面をまたぐ機能や、戻り先制御の実装時には、情報の保持手段がバグやユーザビリティに直結するためです。


✅ 1. なぜ「使い分け」が必要なのか?

例えば、以下のような画面遷移を想定します。

掲示板一覧 → 掲示板詳細 → スレッド詳細 → 投稿

このように「掲示板ID」「スレッドID」「ユーザーID」などが必要なデータは、各画面や処理で異なるライフサイクルを持っています。

データ名 使用タイミング 適切な保持方法
ユーザーID ログイン後〜ログアウトまで セッション
掲示板ID 掲示板詳細参照時 URLパラメータ
スレッドID スレッド参照・投稿時 セッション
投稿内容 一時的(フォーム入力) リクエスト

このように、「情報のライフサイクル」 に基づいて、保持方法を明確に分けることがポイントです。


✅ 2. セッションを使うべきケース

以下のようなケースではセッションを使うのが適しています。

  • ログイン中のユーザー情報(ユーザーID、権限など)

  • 投稿時の投稿時のスレッドID(同一スレッドへの連続投稿など)

  • 「戻る」や「キャンセル」時に再表示する対象情報の保持

📌 特に「戻る」や「投稿後に再表示する対象スレッド」は、URLに埋め込むのではなくセッションで持つことで、リダイレクト後も正しく再取得できます。


✅ 3. URLパラメータを使うべきケース

一方で、以下のような情報はURLパラメータとして渡すのが適しています。

  • 掲示板ID(掲示板詳細を直接参照するケースが多いため)

  • スレッドID(スレッド詳細リンクなど明示的な遷移時)

📌 URLに情報が見えることで、ユーザーがブックマーク可能、またはSEO対応にもなる利点があります。


📝 4. 実装例(実プロジェクトに即した記述)

✅ PostAction.java 抜粋

投稿処理において、投稿対象の thread_id はセッションに保持されています。

// セッションから thread_id を取得
Integer threadId = (Integer) session.get("thread_id");

// Postオブジェクトに thread_id を設定
post.setThread_id(threadId);

// 再度 thread_id をセッションに保存(PostListActionへの遷移のため)
session.put("thread_id", threadId);

  • 投稿時に thread_id をセッションから取得し、投稿内容と紐づける。
  • 画面遷移(例:投稿一覧再取得)後も同じスレッドが対象になるよう、thread_id をセッションに再格納している。

✅ BoardDetailAction.java 抜粋

掲示板ID(board_id)は、URLパラメータから取得しています。

// URLパラメータから掲示板IDを取得(内部的にServletRequestを使用)
private int getBulletinboardIdFromUrl() {
    HttpServletRequest request = ServletActionContext.getRequest();
    int id = Integer.parseInt(request.getParameter("id"));
    logger.debug("Bulletinboard ID from URL: " + id);
    return id;
}
  • URLに含まれる id をパースして、掲示板詳細取得・スレッド作成リンク用の処理に使用。
  • このIDは、掲示板のスレッド一覧取得や、スレッド作成画面遷移のリンク生成に活用される。

✅ まとめ表

データ名 使用箇所 取得方法 保存対象
user_id ログイン後各画面共通 ログイン時セッションに格納 セッション
thread_id 投稿処理 (PostAction) セッションから取得/保存 セッション
board_id 掲示板詳細 (BoardDetailAction) URLパラメータから取得 URL(明示的)

✅ 5. 設計ポイントまとめ

  • 一時的な操作対象(スレッドなど)はセッションに保持

  • 複数ユーザーが閲覧・遷移できるもの(掲示板など)はURLパラメータで渡す

  • 「戻る」「キャンセル」などの機能では、セッション上のIDを使って状態復元

このように設計することで、Struts2のリダイレクト・画面遷移に対応した、堅牢なWebアプリが実現できます。


🔍 補足:なぜ「掲示板ID」はURLパラメータで渡すのか?

掲示板ID(board_id)のような情報を「セッションで持てばいいのでは?」と考えるのは自然な発想です。
実際、thread_id はセッションで保持しているのだから、統一した方がスッキリするようにも思えます。

しかし、以下のような理由から「掲示板IDはURLパラメータで渡す方が適している」とされています。


✅ 理由①:直接アクセスやブックマークを許容したい場合

掲示板の詳細画面は、ログインユーザーであれば 誰でも見られる情報 です。
そのため、次のような使い方が求められます。

  • URLを直接入力してアクセスできる

  • ブックマークして後から再訪できる

  • 他人にURLリンクを共有できる(社内チャット等)

こういった用途をサポートするには、https://example.com/board/detail?id=3 のように、URLにIDが含まれていることが重要です。
一方、セッションで保持する方式では、前の画面を経由しないと正しく動作できません。

✅ 理由②:RESTful設計やWebの基本原則に則る

REST的な観点では、URLは一意なリソースを表現するものとされます。

GET /board/detail?id=3 → 掲示板ID=3の詳細情報

このように明示的なURL設計にすることで:

  • どのリソースを見ているかが明確になる

  • クローラやリンク解析にも有利

  • ブラウザの履歴・戻る機能とも親和性が高い

このため、読み取り専用・共有可能な情報はURLパラメータで渡すのが自然とされています。


✅ 理由③:「IDを見せたくない」場合はどうする?

「URLにIDを出したくない」「内部IDを見せるのがセキュリティ的に心配」というケースもあります。
その場合は、以下のような対策が考えられます。

✅ 方法1:トークンでマスキング

/board/detail?token=abcde12345

  • トークンとIDの対応関係をサーバー側で管理。

  • ユーザーにはIDを見せず、安全なURLでアクセス可能。

✅ 方法2:セッションに保持(ただし注意点あり)

  • 前画面でセッションにIDを保存 → 詳細画面で使用。

  • ただし、直接URLを開くことができない・戻る機能と相性が悪いなどの制約があります。


✅ 結論:設計目的に応じて使い分ける

使用ケース URLパラメータ セッション保持
リンク共有、直接アクセス、再訪を許可したい ✅ 向いている ❌ 不向き
ログインユーザー専用・一時的な操作対象 ❌ 不向き ✅ 向いている
IDを秘匿したい(セキュリティ的配慮) トークン方式などで対応 ✅ 可能

このように、「なぜURLパラメータなのか?」という観点を押さえることで、より明確な画面遷移設計ができるようになります。


✨ 補足A:セッションでIDを保持する設計例(実装あり)

✅ 目的

一時的な操作対象(スレッドIDなど)をセッションに保持することで、
画面遷移後も状態を維持し、不要なパラメータの受け渡しを避けることができます。


✅ 使用ケースの一例(※本プロジェクトの設計とは異なる)

  • スレッド詳細画面でスレッドIDをセッションに保存し、投稿画面でそのIDを利用
  • 投稿完了後、セッションに保持していたIDを使って再表示する

💡 本プロジェクトでは「投稿フォームと投稿一覧」が同一のスレッド詳細画面に統合されています。
本例は、画面分離型の設計パターンにおけるセッション活用例です。


✅ 実装例(PostAction.java)

// セッションからスレッドIDを取得
Integer threadId = (Integer) session.get("thread_id");

// 投稿オブジェクトにスレッドIDをセット
post.setThread_id(threadId);

// 投稿データの保存処理など...

// 投稿完了後、同一スレッドの再表示に備えて再度スレッドIDをセッションに保存
session.put("thread_id", threadId);

✅ 利点と注意点

項目 内容
✅ 利点 URLがスッキリする/セキュリティ上IDを隠せる/リダイレクトで状態維持可能
⚠️ 注意点 セッションに依存しすぎると、画面の再現性や状態管理が煩雑になる

✅ 活用のポイント

  • IDをセッションに入れる対象は「一時的に操作するもの」に限定

  • 投稿、編集、削除など「ユーザー固有の操作」において有効

  • セッションタイムアウトや多重ログイン時の考慮も必要


✅ 説明補足

  • 実装はあくまで「スレッド詳細 → 投稿 → 戻る」のような画面遷移型で使われる典型パターンの例です。
  • 本プロジェクトでは、画面遷移せずに同一画面内で完結する設計のため、完全一致ではありません。
  • しかし、読者が他のWebアプリ開発でセッション設計に悩んだ際に、参考になる構成となっています。

✨ 補足B:トークン方式でIDをURLから隠す方法(実装あり)

✅ 目的

URLにID(掲示板ID、スレッドIDなど)を表示したくない場合、
ランダムなトークンに変換してやり取りすることで、IDを直接露出せずに遷移を実現できます。


✅ 使用ケースの一例

  • 掲示板詳細画面やスレッド詳細画面へのアクセスに「ランダムトークン」を使う
  • トークンと実IDの対応表をサーバー側(DBまたはセッション)で管理

💡 URLに ?id=123 のようにIDが表示されることを避けたいときに有効な設計です。


✅ 実装ステップ(簡易例)

🔹 ステップ1:トークンを生成してセッションに保存

// 例:掲示板IDからトークンを生成
String token = UUID.randomUUID().toString();
session.put("token_" + token, bulletinboardId);

// URLにトークンを付与してリンク生成
String url = "boardDetail.action?token=" + token;

🔹 ステップ2:トークンを受け取ってIDに変換

HttpServletRequest request = ServletActionContext.getRequest();
String token = request.getParameter("token");

// セッションから実IDを取得
Integer boardId = (Integer) session.get("token_" + token);

if (boardId == null) {
    // 不正アクセス or 有効期限切れの処理
    return "error";
}
画面 → トークン生成 → リンク生成 → トークン受信 → ID復元

✅ 利点と注意点

項目 内容
✅ 利点 IDをURLに表示しない/URLコピー・共有時にも安全性が向上
⚠️ 注意点 トークンの有効期限・管理が必要/セッション肥大化に注意

✅ 活用のポイント

  • セキュリティ重視の設計が必要な場面で有効(例:管理機能・内部画面)

  • トークンの有効期限やアクセス権限を必ず検証する

  • トークンをDBに保存する方式も可(ログインユーザー単位で管理)


✅ 応用例

  • パスワード再発行メールでの一時トークンリンク

  • 管理画面でのURL保護(内部IDを見せない)


🔍 補足のまとめ

  • 補足Aは「セッションにIDを保持」するケース
  • 補足Bは「URLにIDを見せずトークンに置き換える」ケース

両者とも、「セキュリティ」や「画面状態の保持」を考慮した設計パターンです。プロジェクトの要件に応じて、適切な方式を選ぶ指針として活用できます。


✨ シリーズまとめ(Vol.11.2.xx アクション層設計)


🧭 関連記事(Vol.11.xxxシリーズ)

連番 タイトル 内容分類
Vol.11.0 Struts2が提供してくれる便利機能まとめ9選 導入&概要
Vol.11.1 自動注入とステートレスActionの仕組み フレームワーク内部理解
Vol.11.2 UX改善に効く!アクション層設計と入力制御の極意(プロローグ) UX設計・アクション層総論
Vol.11.2.1 【実践編】Struts2アクション層の役割と設計パターン(Command型 / UIアクション分離など) アクション設計パターン
Vol.11.2.2 【UX重視】戻るボタン・キャンセル処理の設計手法と「戻り先管理」のスマート実装 戻り先制御とUX設計
Vol.11.2.3 【設計ノウハウ】多画面遷移時のパラメータ受け渡し・保持戦略(セッション vs hidden vs URL) パラメータ多重管理
Vol.11.2.5 【トラブル防止】アクション層の共通処理とメンテナブルなBaseAction設計 アクション共通化/保守性
Vol.11.3 Struts2の defaultStack とは?Interceptorの中身を詳しく追ってみる Interceptor
Vol.11.3.2 🔧 Vol.11.3.2 独自Interceptorの作り方と使い所 Struts2のカスタマイズを“実践で使えるレベル”に一歩進めよう Interceptor
Vol.11.4 入門者のための「パラメータ自動バインディング」完全理解ガイド 自動バインディング
Vol.Vol.11.4.1 入門者のための自動バインディング実践パターン集 自動バインディング
Vol.11.5 Struts2の構成理解が“実務レベル”へと進化する決定版 設定ファイル構造
Vol.11.5.1 Struts2の“画面遷移の全体像”を理解するためのマイルストーン記事 設定ファイル構造
Vol.11.6 ActionSupport の便利メソッドと国際化対応 ユーティリティ / i18n
Vol.11.7 validate() / input 戦略とUX設計 開発スタイルの違い
Vol.11.8 アノテーションベースの設定 vs XML定義の比較 開発スタイルの違い
Vol.11.9 バリデーション完全解説(XML / アノテーション) バリデーション(※Vol.8補完)
Vol.11.10 Struts2の「OGNL」ってなに?しくみと使い方をやさしく解説 式言語OGNL解説
Vol.11.11 ModelDriven インターフェースの使いどころと注意点 Model駆動開発
Vol.11.12 SessionAware と RequestAware でセッション/リクエスト管理 セッション管理
Vol.11.13 Resultタイプ完全解説(dispatcher / redirect / stream など) 遷移パターン理解
Vol.11.14 Vol.11.14 ValueStackの中身を理解する – 画面とActionの橋渡し役 Action
Vol.11.15 Interceptorチェーンを自作してみよう(ログ / 認証フィルタ) Interceptor
Vol.11.16 エラー処理と例外ハンドリングの実践パターン ハンドリング設計
Vol.11.17 Struts2でファイルアップロード機能を実装する方法 実装系Tips
Vol.11.18 非同期通信(AJAX)とStruts2の連携方法 フロント連携編
Vol.11.19 セキュリティ対策(CSRF, XSS, パラメータ偽装) セキュリティ対策
Vol.11.20 複数フォームを安全に扱う!セッション管理と動的フォームの考え方 セッション管理
Vol.11.21 Struts2でJSONを返す!REST API連携と非同期通信の基本設計 セッション管理
Vol.11.22 本番環境構成とセキュリティ設計(Apache+Tomcat+Struts2連携) 外部公開

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?