Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

FlashScopeという考え方


こんばんは、阪本です。

「今さらStrutsか」「もうStrutsなんて古い」とよく聞く昨今ですが、
そう言いつつも、Strutsを使ってませんか?

そんなあなたにお勧めなのが、SpringMVCです!

SpringMVC自体は2003年頃から存在していますが、
いろいろと機能追加がされ、適用範囲の広いフレームワークになっていると思います。

#Playなんかも良いと思いますが、
#元々、エンタープライズ/ミッションクリティカル系の開発が多いためか、
#個人的には、SpringMVCの方が好みだったりしますw


さて、
そう思って、現在のバージョンであるSpringMVC 3.1を見てみると、
FlashScopeが簡単に使えるようになっていたんですね。

FlashScopeとは、画面遷移をリダイレクトで行う際でも、
遷移先に値を渡すための値のスコープ。


そのFlashScopeを用いて値を渡す方法は以下の通り。

まずController。

RedirectTestController.java

@Controller
@RequestMapping("/redirectTest/*")
public class RedirectTestController {
    /**
     * フォームのsubmitボタンが押下されたときに呼ばれます。
     * リダイレクトで完了画面に遷移します。
     *
     * @param attr リダイレクト属性
     * @return リダイレクト先画面
     */
    @RequestMapping(params = "submit")
    public String submit(RedirectAttributes attr) {   // 引数にRedirectAttributesを指定
        attr.addFlashAttribute("message", "メールを送信しました。");  // 遷移先画面に渡したい値を追加
        return "redirect:complete.do";   // リダイレクトで画面遷移
    }

    /**
     * リダイレクトで表示する完了画面を返します。
     *
     * @return 画面
     */
    @RequestMapping(value = "complete")
    public String complete() {
        return "complete";    // complete.jspを表示
    }
}

submitメソッドでは、引数にRedirectAttributes型の引数を定義しています。
この引数のaddFlashAttributeメソッドを呼び出して、
リダイレクト先の画面に渡したい値(今回の例では文字列だが、それ以外のオブジェクトも可)を追加します。
たったこれだけ。

あとは、JSPで画面表示するだけ!


complete.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<!-- headは省略 -->
<body>
<h1>完了画面</h1>
<p>処理が完了しました。</p>
<c:if test="${message != null}">
  <p><c:out value="${message}" /></p>
</c:if>
</body>
</html>

非常に簡単!

完了画面にはリダイレクトで遷移しているので、
完了画面でリロードしても、二重submitは行われません。
また、FlashScopeの値も消えているので、リロード後はメッセージが消えます。

SpringMVCでは、RedirectAttributes#addFlashAttribute() で追加した値は
セッションで管理されます(FlashMapというオブジェクトの中で管理されます)。
画面遷移が完了した瞬間に、セッション(FlashMapオブジェクト)から削除されるので、
セッションにゴミが残らない仕掛けになっています。


ということで、各Scopeのメリット/デメリットをまとめてみました。

スコープ メリット デメリット 用途例
Request Scope 画面表示が完了するとオブジェクトが削除されるため、メモリが節約できる。 リダイレクトによる画面遷移では値を渡せない。 フォームの値
画面表示メッセージ
(フォワードによる画面遷移)
Session Scope アクセスしているユーザがどの画面にアクセスしても、継続して値を保持できる。 大きなオブジェクトをセッションに持つと、アクセス数が増えた時にメモリ不足となる。 ログイン情報
ステートフルな画面の検索条件等
Flash Scope リダイレクトによる画面遷移でも値を渡せる。 リダイレクトによる画面遷移となるため、画面遷移が遅い。 画面表示メッセージ
(リダイレクトによる画面遷移)


データベースの更新が伴う画面遷移をリダイレクトにして、
遷移後に表示するメッセージをFlashScopeで保持するのが、定番の使い方ですね。

では。