假设我们有一个实体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"; }
您不需要仅使用Bean作为参数的@ModelAttribute( parameter )
@ModelAttribute
例如,这些处理程序方法可以很好地处理以下请求:
@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:
@SessionAttributes
Controller
ControllerAdvice
@Controller @RequestMapping("/foos") public class FooController { @ModelAttribute("foo") String getFoo() { return "bar"; // set modelMap["foo"] = "bar" on every request } }
由FooController以下任何转发到的JSP :
FooController
${foo} //=bar
要么
@ControllerAdvice public class MyGlobalData { @ModelAttribute("foo") String getFoo() { return "bar"; // set modelMap["foo"] = "bar" on every request } }
任何JSP:
如果要使用( 方法* )的结果作为 默认值, 请使用@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