当前位置: 首页 > 面试题库 >

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

龚德本
2023-03-14
问题内容
  • @ModelAttribute方法上的参数指示应从模型中检索参数。如果模型中不存在该参数,则应首先实例化该参数,然后将其添加到模型中。一旦出现在模型中,则应从名称匹配的所有请求参数中填充参数的字段。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
  }

示例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只填充独立变量(当然可能是@ModelAttribute类中的字段)。完成控制器后,这些变量将被丢弃,除非将它们输入到模型中。

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

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

是! 正确地说,是让@ModelAttributeSpring使用其默认的Web数据绑定器来填充来自的数据的实例HttpServletRequest。选择将此数据传递回视图取决于程序员。当你使用注释方法时@ModelAttribute,每次代码访问该servlet时都会调用该方法。当你拥有@ModelAttribute方法的参数之一时,我们正在谈论传入的Http表单数据绑定。

Calling@RequestParam是说话的捷径request.getParameter("foo"); 在幕后,Java HttpServletRequest允许你通过执行key-> value查找来从请求对象获取值。返回的值是对象类型。如果你不使用Web应用程序中的Spring,这将是你要键入的内容。

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

如果你使用注释控制器中的方法,则@ModelAttribute("fooBar") FooBar fooBar 的实例FooBar将始终由Spring构造并提供给你的方法。数据绑定起作用的地方是在方法的参数中使用此注释时;Spring查看的实例,看看HttpServletRequest它是否可以将请求中的数据与的实例上的right属性进行匹配FooBar。这是基于Java属性约定的,在该约定中,你有一个诸如foo和的字段,它们分别是和公共获取器和设置器,称为getFoosetFoo。这看起来似乎很神奇,但是如果你违反约定,那么Spring数据绑定将停止工作,因为它无法从你的位置知道将数据绑定到何处HttpServletRequestFooBar,但不会将属性设置为请求中的任何值。



 类似资料:
  • 我通过Spring文档了解了,他们给出了如下解释: 方法参数注释指示方法参数应绑定到HTTP请求主体的值。例如: 您可以使用将请求正文转换为方法参数。负责将HTTP请求消息转换为对象,并将对象转换为HTTP响应正文。 支持使用和进行基于注释的处理。在Spring 3.0中,得到扩展,以支持,并且默认情况下注册了以下: ... 但我感到困惑的是,他们写在文件上的那句话是 他们这么说是什么意思?谁能给

  • 问题内容: 我听到有人说“ JVM一定是Java解释器,但Java解释器不一定是JVM”。真的吗? 我的意思是Java解释器和JVM之间有区别吗? 问题答案: 是,有一点不同。 Java虚拟机: 一种软件“执行引擎”,可安全,兼容地执行微处理器(无论是计算机还是其他电子设备中)的Java类文件中的字节码。 Java解释器: 交替解码并执行某些代码体中的每个语句的模块。Java解释器解码并执行Jav

  • 有人能解释一下last()和takeLast()方法的区别吗?正如文件所述: last()-将完成信号之前观察到的最后一个元素作为单声道发出,或者如果源为空,则发出NosTouchElementException错误。对于被动版本,请使用takeLast(int) TakeLast()-在此Flux完成之前发出最后N个值。 对我来说是一样的。我不能理解的差异。有人能给我举个简单的例子吗?提前感谢

  • 我的理解是请求参数是方法传递所需的id,而path变量说这个变量应该在请求过程中找到

  • 我有一个控制器,它的GET方法是这样写的: bean是正确的(getter和setter),服务调用返回带有thingId的正确ThingBean,并且显示了我在edit.jsp的JSP页面。 JSP是: 但是,JSP 显示主题和消息的空白值。是的,这些属性上有吸气剂/二传手。 我有一个非常相似的控制器,工作得很好,除了GET - mapped方法的签名中没有@RequestParam。 我在Sp

  • 我试图使用@consume注释bean使用通过spring JmsTemplate发送的JMS消息。当使用JMSTemplate发送消息时,使用者不接收消息。 然而,当使用Camel的ProducerTemplate发送时,将接收消息。 @org.springframework.jms.annotation.jMSListener和@org.apache.camel.consume之间有什么区别?