セッションの値を画面に表示するには?Modelとの連携方法を初心者向けに解説
新人
「Spring MVCでセッションの値を画面に表示したいんですが、どうすればいいですか?」
先輩
「Spring MVCでは、セッションに保存した値をModelを通してビューに渡す方法が基本だよ。」
新人
「セッションとModelの違いがまだよくわかりません。簡単に説明してもらえますか?」
先輩
「もちろん。まずはセッションの役割と、Modelとの関係から整理しよう。」
1. セッションとは何か(基本的な概念と役割)
Webアプリケーションにおけるセッションとは、ユーザーごとの一時的なデータをサーバー側に保持する仕組みです。例えば、ログイン中のユーザー名やカートに入れた商品情報など、ページをまたいでも保持しておきたいデータを管理します。セッションはHTTPが持たない状態管理の機能を補うために使われ、サーバーがユーザーを識別するためのセッションIDと紐づいて動作します。
JavaのSpring MVCでは、セッションを使ってデータを保持することで、ユーザーの操作状態を維持しながらアプリケーションを動かせます。特にログイン状態や選択中の情報を保持する場合に欠かせない仕組みです。
2. Spring MVCにおけるセッションの利用方法の概要
Spring MVCでセッションを扱う方法はいくつかありますが、代表的な方法はHttpSessionを使う方法と、@SessionAttributesアノテーションを使う方法です。
HttpSessionを使う場合は、コントローラのメソッドで引数としてHttpSessionを受け取り、setAttributeやgetAttributeを利用します。これにより、セッションに値を保存したり取得したりできます。
@Controller
public class SessionExampleController {
@GetMapping("/save")
public String saveSession(HttpSession session) {
session.setAttribute("username", "山田太郎");
return "redirect:/show";
}
@GetMapping("/show")
public String showSession(HttpSession session, Model model) {
String username = (String) session.getAttribute("username");
model.addAttribute("name", username);
return "sessionView";
}
}
この例では、/saveにアクセスするとセッションにusernameを保存し、/showでその値をModelに渡してビューで表示します。
3. Modelとの連携の基本的な考え方
Modelは、コントローラからビュー(HTML)へデータを渡すための入れ物です。Spring MVCでは、model.addAttribute("キー", 値)でビューにデータを送ることができます。セッションから取得した値をModelに入れることで、HTMLテンプレート上で表示できるようになります。
@GetMapping("/display")
public String displayData(HttpSession session, Model model) {
String username = (String) session.getAttribute("username");
model.addAttribute("name", username);
return "displayView";
}
上記の例では、セッションから取得したusernameをnameというキーでModelに追加しています。ビューでは${name}で参照できます。
例えば、Thymeleafを使ったHTMLテンプレートは以下のようになります。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>セッションの値表示</title>
</head>
<body>
<h1>セッションに保存された値を表示</h1>
<p th:text="'ユーザー名: ' + ${name}">ユーザー名: 未設定</p>
</body>
</html>
このように、セッションとModelを組み合わせることで、コントローラで保持しているユーザー情報を動的に画面に表示できます。
4. コントローラでセッションの値を取得してModelに渡す方法
Spring MVCでセッションに保存した値を画面に表示するには、まずコントローラでその値を取得し、Modelにセットする必要があります。セッションの値を直接ビューに渡すのではなく、Modelに入れてからテンプレートエンジン(Thymeleafなど)に渡すことで、ビュー側の処理をシンプルに保つことができます。
セッションの値を取得するには、HttpSessionをコントローラメソッドの引数に追加します。そして、getAttributeメソッドで値を取り出し、model.addAttribute()でビューに渡します。
@Controller
public class DisplayController {
@GetMapping("/profile")
public String showProfile(HttpSession session, Model model) {
String username = (String) session.getAttribute("username");
model.addAttribute("displayName", username);
return "profileView";
}
}
このコードでは、セッションからusernameを取得してdisplayNameという名前でModelに登録しています。これにより、ビューでは${displayName}として参照可能になります。
この方法のメリットは、ビュー側で直接セッションの操作を行わずに済むため、コードの責務が明確になり、保守性が向上する点です。
5. HTMLテンプレート(Thymeleaf)でModelの値を表示する方法
Thymeleafでは、Modelに渡された値をth:text属性などを使って簡単に表示できます。Spring MVCとThymeleafを組み合わせることで、サーバーサイドで準備したデータをHTMLに埋め込むことが可能です。
以下は、セッションから取得してModelに入れた値を画面に表示するHTMLテンプレートの例です。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>プロフィール表示</title>
</head>
<body>
<h1>ユーザー情報</h1>
<p th:text="'ログイン中のユーザー名: ' + ${displayName}">ログイン中のユーザー名: 未設定</p>
</body>
</html>
このテンプレートでは、Modelに格納されたdisplayNameを表示しています。もしセッションに値が保存されていない場合は、初期表示として「未設定」が表示されます。
ThymeleafはHTMLタグの属性として値を埋め込む形式を採用しているため、テンプレートの可読性が高く、デザイナーとエンジニアが共同で作業しやすいのも特徴です。
6. セッションとModelを併用する際の注意点(スコープや値の更新タイミング)
セッションとModelを併用する場合には、いくつかの注意点があります。まず、スコープの違いを理解しておくことが大切です。Modelは基本的にリクエストスコープであり、そのリクエスト中だけデータが保持されます。一方、セッションはユーザー単位で複数リクエスト間にわたってデータを保持します。
つまり、同じユーザーが複数のページにアクセスする場合、セッションの値は引き継がれますが、Modelの値はページを移動するたびに失われます。このため、ユーザー情報や設定値のように複数ページで利用する場合はセッションに保存し、表示用に一時的に使う値はModelにセットするのが適切です。
また、値の更新タイミングにも注意が必要です。セッションに保存している値を変更した場合、その値は次のリクエスト以降で反映されます。Modelにセットした値は、そのリクエストの中でのみ有効です。この違いを意識しないと、「画面に表示される内容が更新されない」というトラブルの原因になります。
例えば、次のコードではセッションに保存しているユーザー名を更新し、そのまま画面表示する例を示しています。
@PostMapping("/updateName")
public String updateName(@RequestParam String newName, HttpSession session, Model model) {
session.setAttribute("username", newName);
model.addAttribute("displayName", newName);
return "profileView";
}
この実装では、セッションの値を更新すると同時にModelにも同じ値を入れているため、更新後の画面にもすぐ反映されます。このように、セッションとModelのスコープの違いを理解し、適切に使い分けることが重要です。
さらに、セッションはサーバーのメモリを消費するため、不要になった値はremoveAttribute()で削除することも忘れないようにしましょう。特に長時間利用しないデータを残すと、メモリ効率が悪くなります。
7. セッションの値を更新して画面に反映する実装例
Spring MVCでは、ユーザーが入力した新しい情報をセッションに保存し、同時にModelへも反映させることで、ページ遷移を伴わずに最新の状態を画面に表示できます。これにより、入力直後に最新データが見えるため、ユーザー体験が向上します。
例えば、ユーザー名を更新するフォームと、それを処理するコントローラの例は以下のようになります。
@Controller
public class UpdateController {
@PostMapping("/updateUsername")
public String updateUsername(@RequestParam String username, HttpSession session, Model model) {
// セッションの値を更新
session.setAttribute("username", username);
// Modelにも更新後の値を反映
model.addAttribute("displayName", username);
return "profileView";
}
}
上記の実装では、フォームから送信された新しいユーザー名をHttpSessionに保存すると同時に、Modelにも同じ値をセットしています。これにより、そのリクエスト中に生成されるビューでは最新のユーザー名が即座に表示されます。
Thymeleafでの入力フォーム例は次のようになります。
<form th:action="@{/updateUsername}" method="post">
<label for="username">新しいユーザー名:</label>
<input type="text" id="username" name="username">
<button type="submit">更新</button>
</form>
フォーム送信後、セッションとModelの両方が更新されるため、ユーザーは再読み込みせずに最新の状態を確認できます。
8. セッションの値をクリアする方法(ログアウトやリセット時)
セッションはユーザー情報や状態を保持する便利な仕組みですが、不要になったら速やかにクリアすることが重要です。特にログアウトやデータリセット時には、セッションに残っている情報を削除しないと、古い情報が再び画面に表示される可能性があります。
セッションの値を削除する方法は2つあります。特定の属性だけを削除するremoveAttribute()と、セッション全体を無効化するinvalidate()です。
@Controller
public class LogoutController {
@GetMapping("/logout")
public String logout(HttpSession session) {
// 特定の属性だけ削除する場合
session.removeAttribute("username");
// セッション全体を破棄する場合
// session.invalidate();
return "redirect:/login";
}
}
特定の属性だけ削除したい場合はremoveAttribute()を使います。全てのセッション情報を消したい場合はinvalidate()を使用します。ただし、invalidate()を呼び出すと現在のセッションが完全に破棄され、新しいセッションが作成されるため注意が必要です。
例えばログアウト画面では、ユーザー名や権限情報などセッションに残っている全ての情報を破棄し、ログインページへリダイレクトする実装が一般的です。
9. セッションとModelを使い分けるためのベストプラクティス
Spring MVCで開発を行う際、セッションとModelの役割を明確に分けることが、アプリケーションの品質を高めるポイントです。両者を適切に使い分けることで、パフォーマンスや保守性を維持できます。
まず、セッションは複数リクエスト間で共有される情報を保持するために使います。ログイン状態、ユーザー設定、カート情報など、長期間保持する必要があるデータはセッションに保存します。一方、Modelはそのリクエスト内だけで使用する一時的なデータの受け渡しに適しています。
ベストプラクティスとしては、以下のような方針が推奨されます。
- 複数画面で共通して利用する情報はセッションに保存する。
- その画面だけで必要な情報はModelに保存する。
- セッションの値を変更したら、即時反映が必要な場合は同時にModelにも反映する。
- 不要になったセッションの値は
removeAttribute()やinvalidate()で速やかに削除する。
例えば、ユーザーのプロフィール編集画面では、セッションに保持している情報をフォーム初期値としてModelに渡し、編集後はセッションも更新して常に最新状態を維持します。
@Controller
public class ProfileController {
@GetMapping("/editProfile")
public String editProfile(HttpSession session, Model model) {
String username = (String) session.getAttribute("username");
model.addAttribute("displayName", username);
return "editProfileView";
}
@PostMapping("/editProfile")
public String saveProfile(@RequestParam String username, HttpSession session, Model model) {
session.setAttribute("username", username);
model.addAttribute("displayName", username);
return "profileView";
}
}
このように、セッションとModelの両方を意図的に使い分けることで、ユーザーにとって分かりやすく反応の良い画面表示を実現できます。また、メモリの無駄遣いを防ぎ、システム全体のパフォーマンスも維持できます。