我是 Spring MVC 的新手。请帮我解压文档。
文档
Spring MVC Documentation状态(强调我的):
-
方法参数上的
@ModelAttribute
表示应从模型中检索该参数。如果模型中不存在,则应首先实例化参数,然后将其添加到模型中。一旦出现在模型中,参数的字段应该从具有匹配名称的所有请求参数中填充。 WebDataBinder 类匹配请求参数名称 — 包括查询字符串参数和表单字段 — 按名称对属性字段进行建模。@RequestParam
将请求参数绑定(bind)到 Controller 中的方法参数。
免责声明/说明
我知道 @ModelAttribute
和 @RequestParam
不是同一个东西,不互斥,不扮演相同的角色,可以同时使用,如在 this question - 实际上,@RequestParam
可用于填充 @ModelAttribute
的字段。我的问题更适合他们内部运作之间的差异。
问题:
@ModelAttribute
(用于方法参数,而不是方法)和 @RequestParam
有什么区别?具体来说:
- 来源:
@RequestParam
和@ModelAttribute
是否有相同的来源 信息/人口,即 URL 中的请求参数,可能已作为POST
ed 的表单/模型的元素提供? - 用法:用
@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
以及称为 getFoo
和 setFoo
的公共(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/