@ModelAttribute 注解,啥时候用?
Posted
技术标签:
【中文标题】@ModelAttribute 注解,啥时候用?【英文标题】:@ModelAttribute annotation, when to use it?@ModelAttribute 注解,什么时候用? 【发布时间】:2012-01-31 01:38:16 【问题描述】:假设我们有一个实体 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";
【问题讨论】:
【参考方案1】:方法参数上的@ModelAttribute 表示该参数将从模型中检索。如果模型中不存在该参数,则将首先实例化该参数,然后将其添加到模型中。
【讨论】:
【参考方案2】:你不需要@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
(方法)在每个请求(例如从数据库中)将默认数据加载到模型中,尤其是在使用@SessionAttributes
时。这可以在Controller
或ControllerAdvice
中完成:
@Controller
@RequestMapping("/foos")
public class FooController
@ModelAttribute("foo")
String getFoo()
return "bar"; // set modelMap["foo"] = "bar" on every request
FooController
转发到的任何JSP:
$foo //=bar
或
@ControllerAdvice
public class MyGlobalData
@ModelAttribute("foo")
String getFoo()
return "bar"; // set modelMap["foo"] = "bar" on every request
任何 JSP:
$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
使用@ModelAttribute
(参数)获取存储在flash属性中的对象:
@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
存储的对象
@Controller
@SessionAttributes("attrib1")
public class Controller1
@RequestMapping("/a")
void pathA(Model model)
model.addAttribute("attrib1", new SomeBean("neil")); //this ends up in session due to @SessionAttributes on controller
@RequestMapping("/b")
void pathB(@ModelAttribute("attrib1") SomeBean someBean)
assertEquals("neil", someBean.getName());
GET /a
GET /b
【讨论】:
如何在PUT
方法中使用@ModelAttribute
哇。太有用了
@ModelAttribute 用作参数时如何设置默认值?例如:(@RequestParam(value = "studentName", defaultValue="Alexa")
ModelAttribute 用于获取模型的部分通过 RedirectAttribute 非常有启发性。谢谢
我坦率地认为,@ModelAttribute
是名称最模糊、描述不直观且文档记录最差的注释之一。它给很多人带来了如此多的模棱两可、困惑和头疼……【参考方案3】:
您的问题似乎已经得到解答:
What is @ModelAttribute in Spring MVC?
总结答案和博文:当您希望表单支持对象(Person 的实例)在请求之间保持不变时。
否则,如果没有注释,请求映射方法将假定 Person 是一个新对象,并且绝不会链接到您的表单支持对象。顺便说一句,海报引用的博文真的很棒,绝对是必读的。
【讨论】:
...但是除非您使用 RedirectAttributesModelMap,否则 Model 中的值不会跨请求持久保存?初始化?以上是关于@ModelAttribute 注解,啥时候用?的主要内容,如果未能解决你的问题,请参考以下文章