Play Frameworkでフラッシュメッセージを表示する方法!Twirlビューでの通知実装ガイド
生徒
「先生、データの保存が終わった後に『保存しました!』というメッセージを画面に出したいのですが、ページを移動すると消えてしまうような一時的な通知はどうやって作るんですか?」
先生
「それはフラッシュメッセージ(Flash Scope)という機能を使えば実現できますよ。次のリクエストの間だけデータを保持してくれる特別な仕組みなんです。」
生徒
「次の画面を表示した時だけ出て、リロードすると消えるメッセージですね。Play Frameworkではどう書くんですか?」
先生
「コントローラでメッセージをセットして、ビューでそれを受け取るだけです。具体的な手順を詳しく見ていきましょう!」
1. フラッシュメッセージとは?
Webアプリケーションを開発していると、ユーザーがフォームを送信した後に「登録が完了しました」とか「入力内容にエラーがあります」といった通知を表示したい場面がよくあります。 しかし、通常のWebの仕組み(HTTP)では、ページを移動(リダイレクト)すると前の画面の状態はすべて消えてしまいます。
そこで役立つのが、Play Frameworkのフラッシュスコープ(Flash Scope)です。 これはセッションの一種ですが、「次のリクエストまで」という非常に短い有効期限を持っています。 一度画面に表示されると自動的に削除されるため、一時的な通知メッセージを出すのに最適な仕組みなのです。
2. Javaコントローラでのメッセージ設定方法
まずは、Javaのコントローラ側でどのようにメッセージを送信するのかを確認しましょう。
Play Frameworkの Result オブジェクトには、フラッシュメッセージを付与するための flashing メソッドが用意されています。
package controllers;
import play.mvc.*;
public class MessageController extends Controller {
public Result submitForm() {
// データの処理が完了したと仮定して、一覧画面へリダイレクト
// flashing("キー", "メッセージ内容") を使います
return redirect(routes.MessageController.index())
.flashing("success", "データの保存に成功しました!");
}
public Result index() {
return ok(views.html.index.render());
}
}
上記のコードでは、success というキー名でメッセージを登録しています。
このキー名は自由に決められますが、一般的には success(成功)、danger(エラー)、info(お知らせ)などが使われます。
3. Twirlテンプレートでの表示処理
次に、コントローラから送られてきたフラッシュメッセージを、Twirlテンプレート(ビュー)側で表示させる方法を解説します。
Twirlでは @flash という特殊な変数を使って、簡単に値を取り出すことができます。
@()
<!DOCTYPE html>
<html>
<head>
<title>フラッシュメッセージのテスト</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
</head>
<body class="container mt-5">
@* フラッシュメッセージがある場合のみ表示する *@
@flash.get("success").map { message =>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<i class="bi bi-check-circle-fill"></i> @message
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
}
<h1>メインコンテンツ</h1>
<p>ここにページの内容が表示されます。</p>
</body>
</html>
@flash.get("キー名") は、値が存在する場合にのみ中身を実行する map 処理と組み合わせるのがTwirlの定番の書き方です。
これにより、メッセージがない時に空のタグが出てしまうのを防げます。
4. Bootstrapと連携した多彩な通知デザイン
フラッシュメッセージは単なるテキストですが、BootstrapなどのCSSフレームワークと組み合わせることで、一気に「プロっぽい」画面になります。 エラー時と成功時で色を使い分ける例を見てみましょう。
@flash.get("success").map { msg =>
<div class="alert alert-success">@msg</div>
}
@flash.get("error").map { msg =>
<div class="alert alert-danger">@msg</div>
}
@flash.get("info").map { msg =>
<div class="alert alert-info">@msg</div>
}
このように、コントローラ側でセットするキー名を変えるだけで、ユーザーに対して視覚的に分かりやすいフィードバックを与えることができます。
5. レイアウトテンプレートでの共通化
フラッシュメッセージの表示コードを全てのページに書くのは非効率です。 以前学習した「レイアウトテンプレート(main.scala.htmlなど)」に記述しておけば、どのページへ遷移しても自動的にメッセージが表示されるようになります。
@(title: String)(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-3">
@* 共通の通知エリア *@
@flash.get("success").map { m => <div class="alert alert-success">@m</div> }
@flash.get("error").map { m => <div class="alert alert-danger">@m</div> }
@* 各ページの中身 *@
@content
</div>
</body>
</html>
この共通化を行うだけで、開発者はコントローラで flashing を呼び出すだけで良くなり、デザインの統一感も保たれます。
6. 複数のメッセージを送る方法
一つの操作で複数のメッセージを送りたい場合は、Java側で flashing の後にさらにデータを追加することができます。
ただし、一度のリクエストで送れるデータ量には上限(クッキーのサイズ制限)があるため、あまりに長い文章を送るのには向いていません。
public Result multiMessage() {
return redirect(routes.MessageController.index())
.flashing("success", "完了しました")
.addingToFlash("info", "プロフィールの更新も忘れないでください");
}
addingToFlash メソッドを使えば、既存のフラッシュデータに新しい情報を追記していくことができます。
7. フラッシュとセッションの違い
初心者の方が混同しやすいのが「セッション」と「フラッシュ」の違いです。 どちらもクッキーを利用してデータを保存しますが、その「寿命」が決定的に違います。
- セッション: ユーザーがブラウザを閉じるまで(または期限が切れるまで)ずっと残ります。ログイン情報などに使います。
- フラッシュ: 次のページが表示された瞬間に消えます。今回のような一時的な通知に使います。
「ログインに成功しました」というメッセージをセッションに入れてしまうと、ユーザーがログアウトするまでずっとそのメッセージが出続けてしまう……といったミスが起きがちです。 通知には必ずフラッシュを使うようにしましょう。
8. JavaScriptと組み合わせた動的な通知
最近のWebサイトでは、メッセージが数秒後にふわっと消える演出(トースト通知)をよく見かけます。 Twirlで出力したフラッシュメッセージにJavaScriptを組み合わせれば、こうした高度なUIも簡単に作れます。
@flash.get("success").map { msg =>
<div id="flash-msg" class="alert alert-success">@msg</div>
<script>
setTimeout(function() {
var msg = document.getElementById('flash-msg');
if(msg) msg.style.display = 'none';
}, 3000); // 3秒後に消す
</script>
}
9. セキュリティと日本語の扱い
Play Frameworkのフラッシュメッセージは、ブラウザのクッキーに保存されます。 デフォルトで署名がなされているため改ざんは難しいですが、ユーザーに見られて困る機密情報は入れないようにしましょう。
また、日本語などのマルチバイト文字も問題なく扱えますが、非常に長い日本語メッセージをフラッシュに入れると、クッキーの容量制限を超えてしまい、メッセージが届かない原因になることがあります。 通知は短く簡潔に、が基本のルールです。
10. ユーザー体験(UX)を向上させるために
フラッシュメッセージは、ユーザーが自分の操作が正しく受け付けられたかを知るための大切な道標(みちしるべ)です。 ただメッセージを出すだけでなく、アイコンを付けたり、成功と失敗で色を変えたりといった細かな配慮が、使いやすいWebアプリケーションへと繋がります。
Play Frameworkの flashing と Twirl の @flash をマスターして、ユーザーに優しい親切なサイト作りを目指してくださいね!
まずは簡単な「保存完了」メッセージから実装してみるのがおすすめです。