@ModelAttribute注释,什么时候使用它?

时间:2011-12-31 12:41:50

标签: spring-mvc annotations

假设我们有一个实体Person,一个控制器PersonController和一个edit.jsp页面(创建一个新的或编辑一个现有的人)

控制器

@RequestMapping(value = "/edit", method = RequestMethod.POST)
public String editPerson(@RequestParam("fname") String fname, Model model) {
    if(fname == null || fname.length() == 0){
        model.addAttribute("personToEditOrCreate", new Person());
    }
    else{
        Person p = personService.getPersonByFirstName(fname);
        model.addAttribute("personToEditOrCreate", p);
    }

    return "persons/edit";
}

@RequestMapping(value = "/save", method = RequestMethod.POST)
public String savePerson(Person person, BindingResult result) {

    personService.savePerson(person);
    return "redirect:/home";
}

edit.jsp文件

<form:form method="post" modelAttribute="personToEditOrCreate" action="save">
    <form:hidden path="id"/> 
    <table>
        <tr>
            <td><form:label path="firstName">First Name</form:label></td>
            <td><form:input path="firstName" /></td>
        </tr>
        <tr>
            <td><form:label path="lastName">Last Name</form:label></td>
            <td><form:input path="lastName" /></td>
        </tr>
        <tr>
            <td><form:label path="money">Money</form:label></td>
            <td><form:input path="money" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="Add/Edit Person"/>
            </td>
        </tr>
    </table> 

</form:form>

我尝试上面的代码(不使用savePerson方法中的@ModelAttribute注释,它工作正常。为什么以及何时需要将注释添加到person对象:

@RequestMapping(value = "/save", method = RequestMethod.POST)
public String savePerson(@ModelAttribute("personToEditOrCreate") Person person, BindingResult result) {

    personService.savePerson(person);
    return "redirect:/home";
}

3 个答案:

答案 0 :(得分:55)

您不需要@ModelAttribute参数)只是将Bean用作参数

例如,这些处理程序方法可以正常处理这些请求:

@RequestMapping("/a")
void pathA(SomeBean someBean) {
  assertEquals("neil", someBean.getName());
}

GET /a?name=neil

@RequestMapping(value="/a", method=RequestMethod.POST)
void pathAPost(SomeBean someBean) {
  assertEquals("neil", someBean.getName());
}

POST /a
name=neil

使用@ModelAttribute方法)在每个请求中将默认数据加载到模型中 - 例如从数据库加载,尤其是在使用{{1}时}。这可以在@SessionAttributesController

中完成
ControllerAdvice

@Controller @RequestMapping("/foos") public class FooController { @ModelAttribute("foo") String getFoo() { return "bar"; // set modelMap["foo"] = "bar" on every request } } 转发的任何JSP:

FooController

${foo} //=bar

任何JSP:

@ControllerAdvice
public class MyGlobalData {

  @ModelAttribute("foo")
  String getFoo() {
    return "bar";  // set modelMap["foo"] = "bar" on every request
  }

}

如果要将${foo} //=bar 方法)的结果用作默认值,请使用@ModelAttribute参数

@ModelAttribute

使用@ModelAttribute("attrib1") SomeBean getSomeBean() { return new SomeBean("neil"); // set modelMap["attrib1"] = SomeBean("neil") on every request } @RequestMapping("/a") void pathA(@ModelAttribute("attrib1") SomeBean someBean) { assertEquals("neil", someBean.getName()); } GET /a 参数)获取存储在 flash属性中的对象:

@ModelAttribute

使用@RequestMapping("/a") String pathA(RedirectAttributes redirectAttributes) { redirectAttributes.addFlashAttribute("attrib1", new SomeBean("from flash")); return "redirect:/b"; } @RequestMapping("/b") void pathB(@ModelAttribute("attrib1") SomeBean someBean) { assertEquals("from flash", someBean.getName()); } GET /a 参数)获取@ModelAttribute

存储的对象
@SessionAttributes

答案 1 :(得分:2)

您的问题似乎已得到解答:

What is @ModelAttribute in Spring MVC?

总结答案和博客文章:当您希望跨请求保留表单支持对象(Person的实例)时。

否则,如果没有注释,请求映射方法将假定Person是一个新对象,并且不会链接到表单支持对象。海报引用的博客文章真的很棒,绝对是必读的。

答案 2 :(得分:0)

方法参数上的@ModelAttribute指示将从模型中检索参数。如果模型中不存在,则首先实例化参数,然后将其添加到模型中。