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

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

文件

Spring MVC Documentation州(强调我的):

> @ModelAttribute on method参数表示应该从模型中检索参数。如果模型中不存在,参数首先被实例化,然后添加到模型中。一旦出现在模型中,参数的字段应该从具有匹配名称的所有请求参数中填充。 WebDataBinder类匹配请求参数名称(包括查询字符串参数和表单域),以按名称对属性字段进行建模。
> @RequestParam将请求参数绑定到控制器中的一个方法参数。

免责声明/澄清者

我知道@ModelAttribute和@RequestParam是不一样的东西,不是互斥的,不执行相同的角色,可以同时使用,如在this question – 确实,@RequestParam可以用来填充@ModelAttribute的字段。我的问题更多的是面向内部运作的区别。

题:

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

来源:Do @RequestParam和@ModelAttribute具有相同的来源
信息/人口,即URL中的请求参数,这些参数可能已作为POSTed的表单/模型的元素提供?
>用法:使用@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
  }

示例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类中的字段)。当控制器完成时,这些变量将被丢弃,除非它们被馈送到模型中。
> @ModelAttribute填充一个类的字段,然后填充要传递给视图的模型的属性

它是否正确?

最佳答案

@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.

不要将“模型”一词与会话混淆。 http对话通常是:HTTP.GET,服务器响应,然后是HTTP.POST。当您使用@ModelAttribute注释时,您总是构建一个您注释的任何实例,这就是让您认为“将模型投入到事件”可能会使变量徘徊。这是不正确的,一旦HttpServletRequest已经完成,这些变量应该不再是浏览器/服务器对话的一部分,除非它们被保存在会话中。

@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数据绑定器来填充HttpServletRequest的数据的实例。选择将此数据传回给视图取决于程序员。当您使用@ModelAttribute注释的方法时,每次代码都会使用该servlet进行调用。当@ModelAttribute作为方法的参数之一时,我们正在谈论传入的Http表单数据绑定。

调用@RequestParam是一个说明request.getParameter(“foo”)的快捷方式;在引擎盖下,Java的HttpServletRequest可以通过执行key>值查找来从请求对象获取值。返回的值为Object类型。如果您没有在Web应用程序中使用Spring,那么这将是您打入很多的内容。

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

如果您使用@ModelAttribute(“fooBar”)注释控件中的方法FooBar fooBar FooBar的一个实例将始终由Spring构造并提供给您的方法。数据绑定在哪里发挥作用,是在Method的参数中使用这个注释的时候? Spring查看HttpServletRequest的实例,并查看它是否可以将请求中的数据与FooBar实例上的正确属性进行匹配。这是基于java属性约定,其中有一个字段,如“foo”和公共getter和setter称为getFoo和setFoo。这可能看起来很神奇,但是如果要破坏约定,那么您的Spring数据绑定将停止工作,因为它将无法知道从何处绑定HttpServletRequest的数据您仍然可以获取一个FooBar的实例,但属性不会被设置为来自请求的任何值。

转载注明原文:java – Spring MVC:请解释@RequestParam和@ModelAttribute之间的区别 - 代码日志