Spring MVC:请解释@RequestParam和@ModelAttribute之间的区别

Lyd*_*lph 46 java spring spring-mvc spring-annotations

我是Spring MVC的新手.请帮我解开文档.

文档

Spring MVC文档声明(强调我的):

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

  • @RequestParam 将请求参数绑定到控制器中的方法参数.

免责声明/澄清器

我知道@ModelAttribute并且@RequestParam不是相同的东西,不是相互排斥的,不执行相同的角色,并且可以同时使用,因为在这个问题中 - 实际上,@RequestParam可以用于填充字段@ModelAttribute.我的问题更多地是针对其内部运作之间的差异.

题:

@ModelAttribute(用于方法参数,而不是方法)和@RequestParam?之间的区别是什么?特别:

  • 来源:待办事项@RequestParam@ModelAttribute具有信息/人口,在URL即请求参数相同的源,其可以被提供作为被窗体/模型的元素POST编?
  • 用法:检索到的变量@RequestParam被丢弃是否正确(除非传递给模型),而检索@ModelAttribute到的变量会自动输入要返回的模型中?

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

例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
  }
Run Code Online (Sandbox Code Playgroud)

例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
}
Run Code Online (Sandbox Code Playgroud)

我目前的理解:

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

  • @RequestParam只填充独立变量(当然可能是@ModelAttribute类中的字段).完成控制器后,这些变量将被丢弃,除非它们已被送入模型.

  • @ModelAttribute 填充类的字段,然后填充要传递回视图的模型的属性

它是否正确?

zmf*_*zmf 41

@RequestParam只填充独立变量(当然可能是@ModelAttribute类中的字段).完成控制器后,这些变量将被丢弃,除非它们已被送入模型.

不要将"模型"这个词与会话混淆.http对话通常是:HTTP.GET,服务器响应,然后HTTP.POST.当您@ModelAttribute使用注释时,您总是在构建一个已注释的实例,这就是让您认为"向模型提供内容"可能会使变量变得更加困难的原因.这是不正确的,一旦HttpServletRequest完成这些变量应该不再是浏览器/服务器对话的一部分,除非它们已保存在会话中.

@ModelAttribute 填充类的字段,然后填充要传递回视图的模型的属性

是! 为了正确,@ModelAttribute告诉Spring使用其默认的Web数据绑定器来填充来自的数据的实例HttpServletRequest.选择将此数据传递回视图取决于程序员.如果有一个带注释的方法@ModelAttribute,则每次代码命中该servlet时都会调用它.当你拥有@ModelAttribute方法的参数之一时,我们正在讨论传入的Http表单数据绑定.

呼叫@RequestParam是说话的捷径request.getParameter("foo"); 在引擎盖下,Java HttpServletRequest允许您通过执行key-> value查找来从请求对象获取值.返回的值是Object类型.如果您没有在Web应用程序中使用Spring,那么这就是您要输入的内容.

当你开始使用Spring时,Spring会更进一步@ModelAttribute.该注释采用数据绑定的概念.数据绑定的目标是控制器中的代码不必request.getParameter("foo1")为每个表单元素调用.想象一下,你有一个包含5个字段的Web表单.如果没有数据绑定,程序员必须手动检索并验证每个字段.程序员必须确保请求包含属性,属性的值存在,以及属性的值是每个字段的预期类型.使用@ModelAttribute告诉Spring为你做这项工作.

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


Har*_*ath 7

@ModelAttribute:绑定整个Java对象(例如Employee)。支持多个请求参数

@RequestParam:绑定单个请求参数(例如firstName)

通常,
@RequestParam最适合读取少量参数。

@ModelAttribute 当您具有包含大量字段的表单时使用。

@ModelAttribute 为您提供其他功能,例如数据绑定,验证和表单预填充。


Sot*_*lis 5

@ModelAttribute带注释的参数由注册的ServletModelAttributeMethodProcessor( 或ModelAttributeMethodProcessor) 处理,带注释的参数由注册的或@RequestParam处理,具体取决于参数类型。RequestParamMethodArgumentResolverRequestParamMapMethodArgumentResolver

HandlerMethodArgumentResolvers以下是 Spring 如何使用这些来解析处理程序方法的参数的说明:

在这两种情况下,@ModelAttribute@RequestParam,要绑定的值都是从ServletRequest参数中检索的。

您可以查看上面提到的类型的源代码,但这里是简单的细节。

对于@ModelAttribute,Spring 将创建参数类型的实例。它将检查该实例的字段,并尝试根据由名称@ModelAttribute和字段名称组成的命名/别名策略将参数值绑定到它们。它通常使用一组Converter实例来转换String(参数值始终是String值)到任何目标字段类型IntegerDate等等。您还可以注册自己的Converter类型以进行自定义转换。您还可以嵌套 POJO 类型。

对于@RequestParam,Spring 将使用相同的Converter实例将参数值直接转换为带注释的参数类型。

请注意,参数值不会被“丢弃”。HttpServletRequest它们在容器的请求处理周期期间存储在 中。您始终可以通过适当的方法访问它们。


归档时间:

查看次数:

36366 次

最近记录:

7 年,8 月 前