【问题标题】:Spring MVC @ModelAttribute methodSpring MVC @ModelAttribute 方法
【发布时间】:2014-09-20 14:30:05
【问题描述】:

关于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";
}   

方法二

@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";
}   

【问题讨论】:

    标签: spring-mvc modelattribute


    【解决方案1】:

    @ModelAttribute annotation 有两个用途,具体取决于它的使用方式:

    在方法级别

    在方法级别使用@ModelAttribute 为模型提供参考数据。 @ModelAttribute 带注释的方法在选择的@RequestMapping 带注释的处理程序方法之前执行。它们有效地使用通常从数据库加载的特定属性预先填充隐式模型。这样一个属性就可以通过 @ModelAttribute 在所选处理程序方法中的注解处理程序方法参数进行访问,并且可能应用了绑定和验证。

    换句话说;使用@ModelAttribute 注释的方法将填充模型中指定的“键”。这发生在@RequestMapping 之前 在方法参数级别

    在方法参数级别

    当您将@ModelAttribute 放在方法参数上时,@ModelAttribute 会将模型属性映射到特定的带注释的方法参数。这就是控制器获取对保存表单中输入数据的对象的引用的方式。

    示例

    方法级别

    @Controller
    public class MyController {
        @ModelAttribute("productsList")
        public Collection<Product> populateProducts() {
            return this.productsService.getProducts();
        }
       }
    

    因此,在上面的示例中,模型中的“productsList”在执行@RequestMapping 之前被填充。

    方法参数级别

    @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 以获取带有示例的详细信息。

    【讨论】:

    • 感谢您的快速回答。我已经进一步细化了这个问题,请提供您的意见。
    • @KamalKishore 请看看我的回答,链接已添加。
    • 感谢您的链接,它很好地解释了 ModelAttribute 的流程。我也很想浏览你的其他博客。
    • 你的注意力不应该是processSubmit方法中的@modelAttribute("productsList")吗?
    【解决方案2】:

    一个并不比另一个好。它们都有另一个目的。

    • 方法:如果您需要始终使用某些属性填充特定控制器的模型,则方法级别 @ModelAttribute 更有意义。
    • 参数:当您想从请求中绑定数据并将其隐式添加到模型时,请在参数上使用它。

    回答您关于更好方法的问题

    我会说方法 2 更好,因为数据是特定于该处理程序的。

    【讨论】:

    • 好的,我明白了。因此,当数据特定于处理程序时,方法 2 更好,并且当数据是通用的并且可以被控制器内的多个处理程序使用时,方法 1 更好。非常感谢。
    猜你喜欢
    • 2013-04-28
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多