Interceptorでリダイレクトを行い、リダイレクト先に値を渡したかったので色々試した結果、
以下のような方法で値を渡すことができた。
public class TestInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws IOException {
// リダイレクト先のパス
String redirectPath = request.getContextPath() + "/redirectPath";
// FlashMapを作成
FlashMap flashMap = new FlashMap();
// 渡したい値とキーを設定する
flashMap.put("key", "リダイレクト先に値を渡す。");
// リダイレクト先のパスを設定する
flashMap.setTargetRequestPath(redirectPath);
// FlashMapManagerを利用して、FlashScopeに値をセット
FlashMapManager flashMapManager = RequestContextUtils
.getFlashMapManager(request);
flashMapManager.saveOutputFlashMap(flashMap, request, response);
// リダイレクト
response.sendRedirect(redirectPath);
return false;
}
}
結局、RedirectViewが行っている処理を実装すればよい。
FlashScopeとは
リダイレクト先まで値を保持するスコープ。
リダイレクトは2度リクエストが発生するので、リクエストスコープでは値を保持できない。
SpringMVCでの仕組み
SpringMVCではFlashMapというオブジェクトを利用してFlashScopeを実現している。
FlashMapオブジェクトには、key、value形式のMapに加えて、リダイレクト先のパスとパラメータを保持するフィールドがある。
RedirectViewでは、RedirectAttributesに設定された値と、リダイレクト先のパス、パラメータを設定したFlashMapを作成し、FlashMapManagerを利用してセッションスコープにそのFlashMapを保存している。
セッションスコープに保存されたFlashMapはDispatcherServlet内でController処理に入る前に、取得処理が行われ、パスとパラメータが一致するFlashMapがある場合は、中身を取り出し、リクエストスコープに格納される。
また、このタイミングでFlashMapオブジェクトは破棄される。
まとめ
RedirectAttributesを利用せずにFlashScopeを利用するためには、
- FlashMapオブジェクトにkey、value形式で渡したい値を設定する。
- リダイレクト先のパスと、リクエストパラメータ(必要なときだけ)をFlashMapに設定する。
- FlashMapManagerで作成したFlashMapを保存する。
- リダイレクトする。