Spring MVC
@ModelAttribute
メソッドに関する質問、コントローラーでモデル属性を設定する@RequestMapping
メソッドと@ModelAttribute
メソッドで個別に属性を設定する方法、どちらがより適切であると考えられますか?
設計の観点から、どのアプローチが以下からより良いと考えられますか:
アプローチ1
@ModelAttribute("message")
public String addMessage(@PathVariable("userName") String userName, ModelMap model) {
LOGGER.info("addMessage - " + userName);
return "Spring 3 MVC Hello World - " + userName;
}
@RequestMapping(value="/welcome/{userName}", method = RequestMethod.GET)
public String printWelcome(@PathVariable("userName") String userName, ModelMap model) {
LOGGER.info("printWelcome - " + userName);
return "hello";
}
アプローチ2
@RequestMapping(value="/welcome/{userName}", method = RequestMethod.GET)
public String printWelcome(@PathVariable("userName") String userName, ModelMap model) {
LOGGER.info("printWelcome - " + userName);
model.addAttribute("message", "Spring 3 MVC Hello World - " + userName);
return "hello";
}
1つは他より優れていません。両方とも別の目的に役立ちます。
@ModelAttribute
はより理にかなっています。データはそのハンドラーに固有であるため、アプローチ2の方が優れていると思います。
@ModelAttribute annotation
は、使用方法に応じて2つの目的を果たします。
メソッドレベルで
モデルの参照データを提供するには、メソッドレベルで@ModelAttribute
を使用します。 @ModelAttributeアノテーション付きメソッドは、選択した@RequestMapping
アノテーション付きハンドラーメソッドの前に実行されます。多くの場合、データベースからロードされる特定の属性を暗黙的なモデルに効果的に事前設定します。そのような属性は、選択されたハンドラーメソッドの@ModelAttribute
注釈付きハンドラーメソッドパラメーターを介して既にアクセスでき、潜在的にバインディングと検証が適用されます。
言い換えると; @ModelAttribute
アノテーションが付けられたメソッドは、指定された「キー」をモデルに取り込みます。これは、メソッドパラメータレベルで@RequestMapping
の前に発生します
メソッドパラメータレベル
メソッドパラメーターに@ModelAttribute
を配置すると、@ModelAttribute
はモデル属性を特定の注釈付きメソッドパラメーターにマップします。これは、コントローラーがフォームに入力されたデータを保持するオブジェクトへの参照を取得する方法です。
例
メソッドレベル
@Controller
public class MyController {
@ModelAttribute("productsList")
public Collection<Product> populateProducts() {
return this.productsService.getProducts();
}
}
そのため、上記の例では、@RequestMapping
が実行される前に、モデルの「productsList
」が入力されます。
メソッドパラメータレベル
@Controller
public class MyController {
@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("product") Product myProduct, BindingResult result, SessionStatus status) {
new ProductValidator().validate(myProduct, result);
if (result.hasErrors()) {
return "productForm";
}
else {
this.productsService.saveProduct(myProduct);
status.setComplete();
return "productSaved";
}
}
}
here をご覧ください。