Spring Boot 基本

Flash Scopeでリダイレクト先にパラメータを渡すためのユーティリティを作成してみた

Flash Scopeを利用すると、セッションを使わなくてもリダイレクト先にパラメータを渡すことができるが、Flash Scopeを利用してリダイレクト先にパラメータを受け渡すユーティリティを作成しておけば、コントローラクラス以外でもパラメータの受け渡しができるようになる。

今回は、そのユーティリティクラスを作成し呼び出してみたので、そのサンプルプログラムを共有する。

前提条件

下記記事の実装が完了していること。

Flash Scopeでリダイレクト先にパラメータを渡してみたFlash Scopeを利用すると、セッションを使わなくてもリダイレクト先にパラメータを渡すことができる。また、リダイレクト終了後に、F...

サンプルプログラムの作成

作成したサンプルプログラムの構成は以下の通り。
サンプルプログラムの構成
なお、上記の赤枠は、前提条件のプログラムから変更したプログラムである。

Flash Scopeを利用してリダイレクト先にパラメータを渡すユーティリティクラスの内容は以下の通り。

package com.example.demo;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

public class DemoUtil {

    /**
     * リダイレクト先に渡すFormオブジェクトのキー
     */
    private static final String REDIRECT_FORM_KEY
            = DemoUtil.class.getName().concat(".REDIRECT_FORM");

    /**
     * リダイレクト先に渡したいFormオブジェクトをFlash Scopeに格納する
     * @param demoForm Formオブジェクト
     */
    public static void setRedirectForm(DemoForm demoForm){
        // 引数がnullの場合はIllegalArgumentExceptionをスロー
        if(demoForm == null){
            throw new IllegalArgumentException("demoForm is null");
        }
        // リクエストが取得できない場合はRuntimeExceptionをスロー
        HttpServletRequest request = ((ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes()).getRequest();
        if(request == null){
            throw new RuntimeException("request is null");
        }
        // リダイレクト先に渡したいFormオブジェクトをFlash Scopeに格納
        FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request);
        flashMap.put(REDIRECT_FORM_KEY, demoForm);
    }

    /**
     * リダイレクト先に渡したいFormオブジェクトをFlash Scopeから取得する
     * @return Formオブジェクト
     */
    public static DemoForm getRedirectForm(){
        // リクエストが取得できない場合はRuntimeExceptionをスロー
        HttpServletRequest request = ((ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes()).getRequest();
        if(request == null){
            throw new RuntimeException("request is null");
        }
        // Flash ScopeからFormオブジェクトを取得
        Map<String, ?> flashMap = RequestContextUtils.getInputFlashMap(request);
        if(flashMap != null){
            return (DemoForm) flashMap.get(REDIRECT_FORM_KEY);
        }
        return null;
    }
}



また、コントローラクラスの内容は以下の通り。

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class DemoController {

    /**
     * Formオブジェクトを初期化して返却する
     * @return Formオブジェクト
     */
    @ModelAttribute("demoForm")
    public DemoForm createDemoForm(){
        DemoForm demoForm = new DemoForm();
        return demoForm;
    }

    /**
     * 入力画面に遷移する
     * @return 入力画面へのパス
     */
    @GetMapping("/")
    public String index(){
        return "input";
    }

    /**
     * 確認画面に遷移するためのリダイレクト遷移を行う
     * @param demoForm demoFormオブジェクト
     * @param mav ModelAndViewオブジェクト
     * @return ModelAndViewオブジェクト
     */
    @PostMapping("/confirm")
    public ModelAndView confirm(DemoForm demoForm, ModelAndView mav){
        System.out.println("confirmメソッド demoForm : " + demoForm);
        // リダイレクト先に渡したいFormオブジェクトをFlash Scopeに格納
        DemoUtil.setRedirectForm(demoForm);
        mav.setViewName("redirect:/confirm_redirect");
        return mav;
    }

    /**
     * 確認画面に遷移する
     * @param mav ModelAndViewオブジェクト
     * @return ModelAndViewオブジェクト
     */
    @GetMapping("/confirm_redirect")
    public ModelAndView confirm_redirect(ModelAndView mav){
        // Flash ScopeからFormオブジェクトを取得し、Formオブジェクトの各値が
        // 取得できることを確認
        DemoForm demoForm = DemoUtil.getRedirectForm();
        System.out.println("confirm_redirectメソッド demoForm : " + demoForm);
        // 画面上でdemoFormの設定値を表示するために、戻り値のModelAndViewオブジェクトに
        // demoFormオブジェクトを設定
        mav.addObject("demoForm", demoForm);
        mav.setViewName("confirm");
        return mav;
    }

    /**
     * 完了画面に遷移する
     * @param mav ModelAndViewオブジェクト
     * @return ModelAndViewオブジェクト
     */
    @PostMapping("/complete")
    public ModelAndView complete(ModelAndView mav){
        // Flash ScopeからFormオブジェクトを取得し、Formオブジェクトがクリアされている
        // ことを確認
        DemoForm demoForm = DemoUtil.getRedirectForm();
        System.out.println("completeメソッド demoForm : " + demoForm);
        mav.setViewName("complete");
        return mav;
    }
}

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-flash-scope-util/demo

サンプルプログラムの実行結果

下記記事とほぼ同じ実行結果になる。

Flash Scopeでリダイレクト先にパラメータを渡してみたFlash Scopeを利用すると、セッションを使わなくてもリダイレクト先にパラメータを渡すことができる。また、リダイレクト終了後に、F...

ただし、出力ログを確認すると、completeメソッドのdemoFormの値がnullになっている点が異なっている。
サンプルプログラムの実行結果

要点まとめ

  • Flash Scopeを利用してリダイレクト先にパラメータを受け渡すユーティリティを作成しておくと、コントローラクラス以外でもパラメータの受け渡しができるようになる。