見出し画像

Spring boot コントローラーの引数における @RequestParam と @ModelAttribute の違い

メモです。用語の使い方が間違っていたら申し訳ないです。


modelへの値の入れ方の違い

@RequestParam はコントローラーで値を受け取った後、model.addAttribute()を使う必要がある。

@org.springframework.stereotype.Controller
@RequestMapping
public class MainController {

    @PostMapping("/main")
    public String postMain(Model model, @RequestParam("text") String text){
        model.addAttribute("text", text);
        return "index";
    }
    
}

@ModelAttribute はコントローラーで値を受け取るのに加え、その値をモデルに属性として加える。(model.addAttribute()を書く必要がない。)

@org.springframework.stereotype.Controller
@RequestMapping
public class MainController {

    @PostMapping("/main")
    public String postMain(@ModelAttribute("text") String text){
        return "index";
    }

}


name属性の扱いの違い

リクエストにより値を受け取る際、
@RequestParamは、変数名がname属性と一致していれば、nameを指定する必要はない。
@ModelAttributeは、必ずnameを指定する必要がある。

@org.springframework.stereotype.Controller
@RequestMapping
public class MainController {

    @PostMapping("/main")
    public String postMain(@RequestParam String text){
        return "index";
    }

}


Formクラスでの受取の違い

Formクラスに値を収納する際は、@ModelAttributeを使用する。

@org.springframework.stereotype.Controller
@RequestMapping
public class MainController {

    @PostMapping("/main")
    public String postMain(@ModelAttribute TextForm textForm){
        model.addAttribute("text",textForm.getText());
        return "index";
    }

}

アノテーションなしでも動く。

@org.springframework.stereotype.Controller
@RequestMapping
public class MainController {

    @PostMapping("/main")
    public String postMain(TextForm textForm){
        model.addAttribute("text",textForm.getText());
        return "index";
    }

}


リダイレクト時の挙動

RedirectAttributesのaddAttribute(またはaddFlashAttribute)で属性に値を与えた場合の受け取りはGETリクエストで値を入れた場合と同じ。ただ、リダイレクト先の@ModelAttributeでFormクラスに自動的に値を収納することはできない。

@org.springframework.stereotype.Controller
@RequestMapping
public class MainController {

    @PostMapping("/redirect")
    public String redirectToMain(RedirectAttributes redirectAttributes, @RequestParam String text){
        redirectAttributes.addAttribute("text", text);
        return "redirect:/main";
    }

    @GetMapping("/main")
    public String postMain(Model model, @RequestParam("text") String text){
        model.addAttribute("text",text);
        return "index";
    }

}

Formクラスを使いたい場合はリダイレクト前にFormに収納。
こうすることにより、urlにtextの値が表示されなくなる。

@org.springframework.stereotype.Controller
@RequestMapping
public class MainController {

    @PostMapping("/redirect")
    public String redirectToMain(RedirectAttributes redirectAttributes, TextForm textForm){
        redirectAttributes.addFlashAttribute("textForm", textForm);
        return "redirect:/main";
    }

    @GetMapping("/main")
    public String postMain(Model model, TextForm textForm){
        model.addAttribute("text",textForm.getText());
        return "index";
    }

}



補足

今回用いたTextFormクラスは以下の通り、最もシンプルなクラス。

public class TextForm {
    
    TextForm(){}
    
    TextForm(String text){
        this.text = text;
    }

    private String text;

    public void setText(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

}


以上のコードはPOSTリクエストでtextを送信することを想定しているが、GETリクエストでも同様の結果になった。
また、index.htmlでは${text}を用いて値を受け取ることを想定。




この記事が気に入ったらサポートをしてみませんか?