什么是Spring MVC中的@ModelAttribute?

Moh*_*nan 354 java spring-mvc modelattribute

@ModelAttributeSpring MVC 的目的和用途是什么?

fas*_*seg 387

@ModelAttribute指的是Model对象的一个​​属性(MVC中的M;)所以假设我们有一个带有表单支持对象的表单,称为"Person"然后你可以让Spring MVC通过使用@ModelAttribute注释将这个对象提供给一个Controller方法:

public String processForm(@ModelAttribute("person") Person person){
    person.getStuff();
}
Run Code Online (Sandbox Code Playgroud)

在这里查看一个示例(Spring 2.5),另请参阅"在方法参数上使用@ModelAttribute"(Spring 3.1).

另一方面,注释用于定义应该是模型一部分的对象.因此,如果要在模型中引用Person对象,可以使用以下方法:

@ModelAttribute("person")
public Person getPerson(){
    return new Person();
}
Run Code Online (Sandbox Code Playgroud)

这个带注释的方法将允许访问View中的Person对象,因为它会自动添加到Spring的Models中.

请参阅"在方法上使用@ModelAttribute"(Spring 3.1).

希望这有帮助.

  • @fasseg你在第一种情况下实际上并不需要`@ ModelAttribute`. (7认同)
  • @Ryan请参阅http://stackoverflow.com/questions/8688135/modelattribute-annotation-when-to-use-it/26916920#26916920 (3认同)
  • @Neil什么时候需要在方法属性中使用`@ModelAttribute`? (2认同)
  • 您应该包括如何填充 Person 以及如何调用此方法。 (2认同)

Chr*_*ang 131

我知道这是一个古老的线程,但我想我把我的帽子环,看看我能搅浑了水多一点点:)

我发现我最初的理解@ModelAttribute是春天决定将几个注释合二为一的结果.一旦我将它分成几个较小的注释,它就变得更加清晰了:

对于参数注释,可以认为是@ModelAttribute等价的,@Autowired + @Qualifier即它试图从Spring托管模型中检索具有给定名称的bean.如果找不到指定的bean,而不是抛出错误或返回null,它隐含地承担了@Bean使用默认构造函数创建新实例的角色,并将bean添加到模型中.

对于方法注释,可以认为是@ModelAttribute等价的@Bean + @Before,即它将用户代码构造的bean放在模型中,并且在请求处理方法之前总是调用它.

形象地说,我看到@ModelAttribute如下(请不要字面意思!!):

@Bean("person")
@Before
public Person createPerson(){
  return new Person();
}

@RequestMapping(...)
public xxx handlePersonRequest( (@Autowired @Qualifier("person") | @Bean("person")) Person person, xxx){
  ...
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,Spring做出了做出@ModelAttribute无所不包的注释的正确决定; 没有人想看一个注释smorgasbord.

  • 绝对不.我只是使用更简单的注释来解释这个复杂的注释.请从概念上理解我的解释,而不是字面意思. (10认同)
  • @Zombies添加`@Scope("request")``然后:) (4认同)
  • 嗯,@ Bean默认是单身.我不确定这里适用相同的概念. (2认同)

Lea*_*eat 24

对于我的风格,我总是使用@ModelAttribute从spring form jsp中捕获对象.例如,我在jsp页面上设计表单,该表单与commandName一起存在

<form:form commandName="Book" action="" methon="post">
      <form:input type="text" path="title"></form:input>
</form:form>
Run Code Online (Sandbox Code Playgroud)

我用跟随代码捕获控制器上的对象

public String controllerPost(@ModelAttribute("Book") Book book)
Run Code Online (Sandbox Code Playgroud)

并且书的每个字段名必须与表单子元素中的路径匹配

  • `catch`动词准确描述了`@ ModelAttribute`所做的工作.尼斯. (4认同)
  • 今年的最佳答案. (3认同)
  • 但是有必要吗?在不使用@ModelAttribute批注的情况下仍然可以正常工作。 (3认同)

Xel*_*ian 21

所以我会尝试以更简单的方式解释它.让我们:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

如Spring MVC文档中所述 - @ModelAttribute注释可用于方法方法参数.当然,我们可以在一个控制器中同时使用它们.

1.方法注释

@ModelAttribute(“cities”)
 public List<String> checkOptions(){
 return new Arrays.asList(new[]{“Sofia”,”Pleven","Ruse”});//and so on
}
Run Code Online (Sandbox Code Playgroud)

这种方法的目的是在模型中添加属性.所以在我们的例子中,cities key将列表new Arras.asList(new[]{“Sofia”,”Pleven","Ruse”})作为Model中的值(您可以将Model视为map(key:value)). 控制器中的@ModelAttribute方法在@RequestMapping方法之前在同一个控制器中调用.

这里我们要添加模型公共信息,这些信息将在表单中用于向用户显示.例如,它可用于填充HTML选择:

在此输入图像描述

2.方法论证

public String findPerson(@ModelAttriute(value="person") Person person) {
    //..Some logic with person
    return "person.jsp";
}
Run Code Online (Sandbox Code Playgroud)

方法参数上的@ModelAttribute指示应从模型中检索参数.所以在这种情况下,我们希望我们在Model person对象中有关键,我们想要获取它的值并将它放到方法参数Person person中.如果不存在或者(有时你拼错了(value ="persson"))那么Spring将不会在模型中找到它并使用其默认值创建空Person对象.然后将获取请求参数并尝试使用其名称将数据绑定在Person对象中.

name="Dmitrij"&countries=Lesoto&sponsor.organization="SilkRoad"&authorizedFunds=&authorizedHours=&
Run Code Online (Sandbox Code Playgroud)

所以我们有名称,它将使用setName(String name)绑定到Person.name.所以

//..Some logic with person
Run Code Online (Sandbox Code Playgroud)

我们可以访问这个带有"Dimitrij"值的填充名称.

当然,Spring可以绑定更复杂的对象,如列表,地图,地图集列表等,但在场景后面,它会使数据绑定变得神奇.

  1. 我们可以同时在参数中使用@ModelAttribute建模带注释的方法和请求方法处理程序.然后我们必须结合规则.

  2. 当然我们有很多不同的情况 - @ModelAttribute方法也可以在@ControllerAdvice中定义,依此类推......


Maj*_*han 11

我知道我迟到了,但我会像他们所说的那样引用,"迟到总比没有好".所以,让我们开始吧,每个人都有自己的方式来解释事情,让我尝试总结一下,并通过一个例子在几个步骤中为您简单化; 假设你有一个简单的表单form.jsp

<form:form action="processForm" modelAttribute="student">
First Name : <form:input path="firstName" /> 
<br><br>
Last Name : <form:input path="lastName" />
<br><br>
<input type="submit" value="submit"/>
</form:form>
Run Code Online (Sandbox Code Playgroud)

path ="firstName"path ="lastName"当调用表单时,这些是StudentClass中的字段/属性,调用它们的getter但是一旦提交,就会调用它们的setter,并且它们的值在modelAttribute =中指示的bean中设置表格标签中的"学生".

我们有StudentController,包括以下方法;

@RequestMapping("/showForm")
public String showForm(Model theModel){ //Model is used to pass data between 
//controllers and views
    theModel.addAttribute("student", new Student()); //attribute name, value
return "form";
}

@RequestMapping("/processForm")
public String processForm(@ModelAttribute("student") Student theStudent){
    System.out.println("theStudent :"+ theStudent.getLastName());
return "form-details";
}

//@ModelAttribute("student") Student theStudent
//Spring automatically populates the object data with form data all behind the 
//scenes 
Run Code Online (Sandbox Code Playgroud)

现在终于有了一个form-details.jsp

<b>Student Information</b>
${student.firstName}
${student.lastName}
Run Code Online (Sandbox Code Playgroud)

那么回到问题什么是Spring MVC中的@ModelAttribute?从源为您的样品定义, http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation@ModelAttribute是结合的方法参数或方法返回值来命名模型属性的注释然后将其公开给Web视图.

实际发生的是它获取由它提交的ur表单的所有值,然后保存它们以便绑定或将它们分配给对象.它与@RequestParameter一样,我们只获取一个参数并将值赋给某个​​字段.唯一的区别是@ModelAttribute保存所有表单数据而不是单个参数.它为您创建一个bean,用于保存表单提交的数据,供开发人员稍后使用.

回顾整个事情.第1步:发送一个请求,我们的方法showForm运行,一个模型,一个临时bean设置名称student转发到表单. theModel.addAttribute("student",new Student());

第2步: 表单提交模型上的modelAttribute ="student"更改了学生,现在它保存了表单的所有参数

第3步: @ModelAttribute("student")Student theStudent 我们获取@ModelAttribute所持有的值,并将整个bean /对象分配给Student.

第4步:然后我们在出价时使用它,就像在页面上显示它一样,就像我一样

我希望它能帮助你理解这个概念.谢谢

  • 非常棒的解释,这就是我在互联网上寻找的内容。感谢上帝,我看到了你的回复 (5认同)

Nit*_*sad 5

以任何Web应用程序为例,无论它是Gmail还是Facebook或Instagram,还是任何其他Web应用程序,都与最终用户与应用程序或UI与后端应用程序之间的数据或信息交换有关。即使在Spring MVC世界中,也有两种交换数据的方法:

  1. 从控制器到用户界面,以及
  2. 从UI到Controller。

我们感兴趣的是如何将数据从UI传递到Controller。这也可以通过两种方式完成:

  1. 使用HTML表单
  2. 使用查询参数。

使用HTML表单:考虑以下情况,

表格提交代表

当我们从Web浏览器提交表单数据时,我们可以在Controller类中作为对象访问该数据。当我们提交HTML表单时,Spring容器会做四件事。它会,

  1. 首先使用request.getParameter方法读取请求中提交的所有数据。
  2. 读取它们之后,它将使用integer.parseIntdouble.parseDouble以及基于数据的数据类型可用的所有其他解析方法将它们转换为适当的Java类型。
  3. 一旦解析,它将创建我们创建的模型类的对象。例如,在这种情况下,正在提交的是用户信息,我们创建了一个名为User的类,Container将为其创建一个对象,并将设置自动输入该对象的所有值。
  4. 然后它将通过将值设置为控制器来移交该对象。

为了使整个工作正常进行,我们必须遵循某些步骤。

内部工作

我们首先需要定义一个模型类,例如User,其中的字段数应与HTML表单中的字段数完全匹配。同样,我们在HTML表单中使用的名称应与我们在Java类中使用的名称匹配。这两个非常重要。名称应匹配,表单中的字段数应与我们创建的类中的字段数相匹配。完成后,容器将自动读取传入的数据,创建此模型的对象,设置值并将其交给控制器。要在Controller内部读取这些值,我们使用@ModelAttribute方法参数上的注释。当我们在Controller中创建方法时,我们将使用@ModelAttribute并向其添加一个参数,该参数将自动使Container提供该对象。

这是用于注册用户的示例代码:

@RequestMapping(value = "registerUser", method = RequestMethod.POST)
public String registerUser(@ModelAttribute("user") User user, ModelMap model) {
    model.addAttribute("user", user);
    return "regResult";
}
Run Code Online (Sandbox Code Playgroud)

希望这个图解说明有所帮助!