java - Spring MVC : please explain difference between @RequestParam and @ModelAttribute

标签 java spring spring-mvc spring-annotations

我是 Spring MVC 的新手。请帮我解压文档。

文档

Spring MVC Documentation状态(强调我的):

    方法参数上的
  • @ModelAttribute 表示应从模型中检索该参数。如果模型中不存在,则应首先实例化参数,然后将其添加到模型中。一旦出现在模型中,参数的字段应该从具有匹配名称的所有请求参数中填充。 WebDataBinder 类匹配请求参数名称 — 包括查询字符串参数和表单字段 — 按名称对属性字段进行建模。

  • @RequestParam 将请求参数绑定(bind)到 Controller 中的方法参数

免责声明/说明

我知道 @ModelAttribute@RequestParam 不是同一个东西,不互斥,不扮演相同的角色,可以同时使用,如在 this question - 实际上,@RequestParam 可用于填充 @ModelAttribute 的字段。我的问题更适合他们内部运作之间的差异。

问题:

@ModelAttribute(用于方法参数,而不是方法)和 @RequestParam 有什么区别?具体来说:

  • 来源: @RequestParam@ModelAttribute 是否有相同的来源 信息/人口,即 URL 中的请求参数,可能已作为 POSTed 的表单/模型的元素提供?
  • 用法:@RequestParam 检索的变量是否被丢弃(除非传递给模型),而用 @ModelAttribute 检索的变量是否正确? code> 会自动输入到要返回的模型中吗?

或者在非常基本的编码示例中,这两个示例之间真正的工作区别是什么?

示例 1:@RequestParam:

// foo and bar are thrown away, and are just used (e.g.) to control flow?
@RequestMapping(method = RequestMethod.POST)
public String testFooBar(@RequestParam("foo") String foo,
@RequestParam("bar") String bar, ModelMap model) {
    try {
     doStuff(foo, bar);
    }
    // other code
  }

示例 2:@ModelAttribute:

// FOOBAR CLASS
// Fields could of course be explicitly populated from parameters by @RequestParam
public class FooBar{
    private String foo;
    private String bar;
   // plus set() and get() methods
}

// CONTROLLER
// Foo and Bar become part of the model to be returned for the next view?
@RequestMapping(method = RequestMethod.POST)
public String setupForm(@ModelAttribute("fooBar") FooBar foobar) {
   String foo = fooBar.getFoo();
   String bar = fooBar.getBar();
   try {
      doStuff(foo, bar);
   }
   // other code
}

我目前的理解:

@ModelAttribute@RequestParam 都询问请求参数以获取信息,但它们使用这些信息的方式不同:

  • @RequestParam 只是填充独立变量(当然可以是 @ModelAttribute 类中的字段)。这些变量将在 Controller 完成后被丢弃,除非它们已被输入到模型中。

  • @ModelAttribute 填充类的字段,然后填充模型的属性以传回 View

这对吗?

最佳答案

@RequestParam just populates stand-alone variables (which may of course be fields in a @ModelAttribute class). These variables will be thrown away when the Controller is done, unless they have been fed into the model.

不要将“模型”一词与 session 混淆。 http session 一般是:HTTP.GET,服务器响应,然后是HTTP.POST。当您使用 @ModelAttribute 注释时,您总是在构建您已注释的任何内容的实例,这就是让您认为“向模型提供东西”可能会使变量持续存在的原因。这是不正确的,一旦 HttpServletRequest 完成,这些变量不应再成为浏览器/服务器对话的一部分,除非它们已保存在 session 中。

@ModelAttribute populates the fields of a class, which then populates an attribute of the model to be passed back to the view

是的!正确地说,@ModelAttribute 告诉 Spring 使用其默认的 Web 数据绑定(bind)器来使用来自 HttpServletRequest 的数据填充某物的实例。选择将此数据传递回 View 取决于程序员。当您有一个使用 @ModelAttribute 注释的方法时,每次代码命中该 servlet 时都会调用它。当您将 @ModelAttribute 作为方法的参数之一时,我们正在讨论传入的 Http 表单数据绑定(bind)。

调用 @RequestParam 是说 request.getParameter("foo") 的快捷方式;在底层,Java 的 HttpServletRequest 允许您通过键->值查找从请求对象中获取值。返回的值是 Object 类型。如果您没有在 Web 应用程序中使用 Spring,那么您会经常输入这些内容。

当您开始使用 @ModelAttribute 时,Spring 会将这个抽象更进一步。此注释采用数据绑定(bind)的概念。数据绑定(bind)的目标是 Controller 中的代码不必为每个表单元素调用 request.getParameter("foo1")。假设您有一个包含 5 个字段的 Web 表单。如果没有数据绑定(bind),程序员必须手动检索和验证这些字段中的每一个。程序员必须确保请求包含该属性,该属性的值存在,并且该属性的值是每个字段所期望的类型。使用 @ModelAttribute 告诉 Spring 为您完成这项工作。

如果您在 Controller 中使用 @ModelAttribute("fooBar") FooBar fooBar 注释方法,则将始终构造一个 FooBar 的实例由 Spring 提供,并提供给您的方法。数据绑定(bind)发挥作用的地方是在方法的参数中使用此注释时; Spring 查看 HttpServletRequest 的实例并查看它是否可以将请求中的数据与 FooBar 实例上的正确属性相匹配。这基于 java 属性约定,其中您有一个字段,例如 foo 以及称为 getFoosetFoo 的公共(public) getter 和 setter。这可能看起来很神奇,但如果你打破约定,你的 Spring 数据绑定(bind)将停止工作,因为它无法知道 在哪里 绑定(bind)来自你的 HttpServletRequest 的数据您仍会获得 FooBar 的实例,但不会将属性设置为请求中的任何值。

关于java - Spring MVC : please explain difference between @RequestParam and @ModelAttribute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29370581/

相关文章:

spring - Grails3 Spring Security Plugin RequestMap模式不起作用

java - 如何让 Hibernate 忽略不在实体中的表列?

java - 在 Spring 3.0 MVC Restful 映射中不重复路径两次

spring-mvc - spring mvc 测试 - 验证注解

java - 缺少的代码是什么?

java - RxJava 2 Activity 销毁时可处置

java - Java 随机的好种子 - 构造迷宫

java - 这些集合允许为空。为什么我不能添加空元素?

Javax 验证不给出错误消息

java - Autowired 在自定义注销处理程序和自定义用户详细信息中给出 null