web-dev-qa-db-ja.com

Spring MVC @ModelAttributeメソッド

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";
}   
15
Kamal Kishore

1つは他より優れていません。両方とも別の目的に役立ちます。

  • メソッド:特定のコントローラーのモデルに特定の属性を常に設定する必要がある場合は、メソッドレベル@ModelAttributeはより理にかなっています。
  • パラメータ:リクエストからのデータをバインドし、暗黙的にモデルに追加する場合、パラメータで使用します。

より良いアプローチに関する質問に答えるために

データはそのハンドラーに固有であるため、アプローチ2の方が優れていると思います。

14
Bart

@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 をご覧ください。

19
Ankur Singhal