Spring MVC:请解释@RequestParam 和@ModelAttribute 之间的区别 [英] Spring MVC: please explain difference between @RequestParam and @ModelAttribute

查看:26
本文介绍了Spring MVC:请解释@RequestParam 和@ModelAttribute 之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new to Spring MVC. Please help me unpack the documentation.

文档

Spring MVC 文档 状态(强调我的):

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

  • @ModelAttribute on a method argument indicates the argument should be retrieved from the model. If not present in the model, the argument should be instantiated first and then added to the model. Once present in the model, the argument’s fields should be populated from all request parameters that have matching names. The WebDataBinder class matches request parameter names — including query string parameters and form fields — to model attribute fields by name.

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

免责声明/澄清

我知道@ModelAttribute@RequestParam 不是一回事,不是相互排斥的,不执行相同的作用,并且可以同时使用,如在这个问题中——确实,@RequestParam 可用于填充 @ModelAttribute 的字段.我的问题更侧重于他们内部工作方式之间的差异.

I know that @ModelAttribute and @RequestParam are not the same thing, are not mutually exclusive, do not perform the same role, and can be used simultaneously, as in this question - indeed, @RequestParam can be used to populate fields of @ModelAttribute. My question is more geared towards the difference between their internal workings.

问题:

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

What is the difference between @ModelAttribute (used on a method argument, not method) and @RequestParam? Specifically:

  • 来源:@RequestParam@ModelAttribute 是否有相同的来源信息/人口,即 URL 中的请求参数,这些参数可能已作为 POST ed 的表单/模型的元素提供?
  • 用法:使用 @RequestParam 检索的变量被丢弃(除非传递到模型中),而使用 @ModelAttribute会自动输入到模型中以返回?
  • Source: Do @RequestParam and @ModelAttribute have the same source of information / population, i.e. request parameters in URL, which may have been supplied as elements of a form / model that was POSTed?
  • Usage: Is it correct that variables retrieved with @RequestParam are thrown away (unless passed into a model), whereas variables retrieved with @ModelAttribute are automatically fed into the model to be returned?

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

Or in very basic coding examples, what is the real working difference between these two examples?

示例 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 都查询请求参数以获取信息,但它们使用此信息的方式不同:

@ModelAttribute and @RequestParam both interrogate the request parameters for information, but they use this information differently:

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

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

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

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

这是正确的吗?

推荐答案

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

@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 完成,这些变量不应再成为浏览器/服务器对话的一部分,除非它们已保存在会话中.

Don't confuse the word "model" with session. The http conversation is generally: HTTP.GET, server response, then HTTP.POST. When you have the @ModelAttribute annotation in use you are always constructing an instance of whatever you have annotated, this is what makes you think that 'feeding things to the model' might make variables stick around. This isn't correct, once the HttpServletRequest has finished those variables should no longer be a part of the browser/server conversation unless they've been saved in a session.

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

@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 表单数据绑定.

Yes! To be correct, @ModelAttribute tells Spring to use its default web data binder to populate an instance of something with data from the HttpServletRequest. Choosing to pass this data back to the view is up to the programmer. When you have a method annotated with @ModelAttribute, it is being called every time code hits that servlet. When you have @ModelAttribute as one of the method's parameters, we are talking about incoming Http form data-binding.

Calling @RequestParam 是说request.getParameter("foo") 的快捷方式;在底层,Java 的 HttpServletRequest 允许您通过执行键->值查找来从请求对象中获取值.返回的值是对象类型.如果您没有在 Web 应用程序中使用 Spring,这就是您要输入的大量内容.

Calling @RequestParam is a shortcut for saying request.getParameter("foo"); under the hood, Java's HttpServletRequest lets you get values from the request object by doing a key->value look up. The value returned is of type Object. This is what you would be typing a lot if you were not using Spring in your web application.

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

Spring then takes this abstraction a step further when you start to use @ModelAttribute. This annotation employs the concept of data-binding. The goal of data-binding is that the code in your controller won't have to call request.getParameter("foo1"), for every form element. Imagine you have a web form with 5 fields. Without data-binding the programmer has to manually retrieve, and validate each of those fields. The programmer has to make sure that the request contains the property, that the property's value exists, and that the property's value is of the type expected for each field. Using @ModelAttribute tells Spring to do this work for you.

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

If you annotate a method in your controller with @ModelAttribute("fooBar") FooBar fooBar An instance of FooBar will always be constructed by Spring, and supplied to your method. Where the data binding comes into play, is when this annotation is used in a Method's parameters; Spring looks at the instance of HttpServletRequest and sees if it can match the data in the request to the right property on an instance of FooBar. This is based off the java properties convention, where you have a field such as foo and public getters and setters called getFoo and setFoo. This might seem magic but if you were to break convention, your Spring data binding would stop working because it wouldn't be able to know where to bind the data from your HttpServletRequest You would still get an instance of FooBar, but the properties would not be set to any values from the request.

这篇关于Spring MVC:请解释@RequestParam 和@ModelAttribute 之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆