Takahiro Octopress Blog

-1から始める情弱プログラミング

Spring Bootでリダイレクト先にパラメータを渡す方法

RedirectAttributesを使ってみよう!

さて、本日は久々にSpring Bootの話です。

皆さんはWebアプリケーションを作る中で、「リダイレクト先にパラメータを渡したい!」なんてことはありませんでしょうか?
筆者は先日、そのような状況に鉢合わせたのですが、ググってみてもなかなか求めている答えが見つからず、少々悩んでしまいました。
GETリクエストであればリダイレクト後にURLからリクエストパラメータが取得できますが、
POSTリクエストやURLにリクエストパラメータを表示するわけにいかない仕様の場合はそうもいきません。

そんなときに役に立つのがRedirectAttributesです。
では、早速、使い方を見ていきましょう。

リダイレクト先に文字列を送る

まずは単純な例から見ていきましょう。
下記はリダイレクト先に文字列をパラメータとして渡す例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// HelloController
@Controller
public class HelloController {
  @RequestMappinf(value = "/", method = RequestMethod.POST)
  public String form(RedirectAttributes redirectAttributes, @RequestParam("name") String name) {
      
      redirectAttributes.addFlashSttribute("name", name);
      return "redirect:/redirectSample";
  }

  @RequestMapping("/redirectSample")
  public String sample(@ModelAttributes("name") String name) {
      
      System.out.println("name: " + name);
      return "sample";
  }
}

実際に動かしてみれば、正しくログが出力されることを確認できるでしょう。
上記でreturn "sample";としているのは単なる例なので、適切なtemplateを指定してあげてください。

リダイレクト先にオブジェクトを送る

続いて、パラメータをまとめて送るパターンです。
今回は下記のように定義されたMyDataを送ってみましょう。
※ソースを簡単にするためにbuild.gradlecompile("org.projectlombok:lombok:1.16.6")を設定して@Dataを利用しています。

1
2
3
4
5
6
7
// MyData.java
@Data
public class MyData {

  private String name;
  private String memo;
}

では、実際にパラメータを送ってみましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// HelloController

@Controller
public class HelloController {

  @RequestMapping(value = "/", method = RequestMethod.POST)
  public String form(RedirectAttributes redirectAttributes, @RequestParam("name") String name, @RequestParam("memo") String memo) {
      
      // MyDataについては後述します
      MyData mydata = new MyData(name, memo);
      ModelMap modelMap = new ModelMap();
      modelMap.addAttribute("mydata", mydata);
      redirectAttributes.addFlashAttribute("model", modelMap);

      return "redirect:/redirectSample";
  }

  @RequestMapping("/redirectSample")
  public String sample(@ModelAttribute("model")ModelMap modelMap) {
      
      MyData mydata = modelMap.get("mydata");
      String name = mydata.getName();
      String memo = mydata.getMemo();
      System.out.println("name: " + name + ", memo: " + memo);

      return "sample";
  }
}

オブジェクトとしてパラメータを送るにはModelMapに一度格納する必要があります。
パラメータを受け取ったあとに型変換して取り出せばOKです。

RedirectAttributesにおけるaddAttributeとaddFlashAttributeの違い

さて、今回はRedirectAttributesaddFlashAttributeを利用しましたが、RedirectAttributesにはaddAttributeというメソッドも存在します。
ではなぜaddFlashAttributeを利用したのか参考までに書いておきます。

RedirectAttributesのaddAttributeはリダイレクト先に文字列としてパラメータを送る

大きな違いはaddFlashAttributeのようにModelMap型でパラメータを送れません。
よって、複数のパラメータを送るには1つずつパラメータをセットするしか方法がありません。

1
2
3
// addAttributeの例
redirectAttributes.addAttribute("name", "hogehoge");
redirectAttributes.addAttribute("memo", "fugafuga");
RedirectAttributesのaddAttributeはリダイレクト先でのパラメータの受取り方が異なる

こちらも大きな違いとなりますが、addFlashAttributeのときのように@ModelAttributeを使ってパラメータを受け取ることができません。
addAttributeの場合、@RequestParameterを使ってパラメータを受取ります。

1
2
3
4
5
// addAttributeの例
@RequestMapping("/redirectSample")
public String sample(@RequestParam("name") String name, @RequestParam("memo") String memo) {
  ...
}
リロード時の挙動が異なる

最後になりますが、
addAttributeaddFlashAttributeではリダイレクト後にリロードすると挙動が異なります。
addAttributeではGETリクエストとしてURLの末尾に?name=hogehoge&memo=fugafugaという形でパラメータが渡されるため、リロードをしてもパラメータを受け取ることができます。

しかし、addFlashAttributeではflashMapを利用したパラメータ渡しとなっています。
よって、リダイレクト後はflashMapからパラメータが残らないため、何もパラメータを受け取ることはできなくなります。

いかがでしたでしょうか?
筆者にとってもSpring Bootに慣れない日々が続きますが、気づいたことや学んだことについてはブログにまとめていきたと思います。
と言ったところで本日はここまで。

Comments