①绑定请求参数到命令对象:放在功能处理方法的入参上时,用于将多个请求参数绑定到一个命令对象,从而简化绑定流程,而且自动暴露为模型数据用于视图页面展示时使用;
②暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用对象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping注解的方法)之前,自动添加到模型对象中,用于视图页面展示时使用;
③暴露@RequestMapping方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为模型数据,用于视图页面展示时使用。
1 暴露表单引用对象为模型数据
在 controller 中所有的方法执行前执行
比如是为表单准备要展示的表单引用对象,如注册时需要选择的所在城市等,而且在执行功能处理方法
@ModelAttribute("cityList")
public List<String> cityList() {
return Arrays.asList("北京", "山东");
}
比如:
/** * 获得所有Addresses,并使他们成为一个model. * 注意@ModelAttribute作用于method级别上时.会在@Controller执行时加载 * method里的方法.即在@Controller执行时@ModelAttribute添加参数. * 返回于该@Controller返回的所有JSP页面. */ @ModelAttribute("addresses") public List<Address> getAllAddresses() { return addressService.getAll(); } /** * 处理和检索一个包含addresses 的JSP Page . */ @RequestMapping(value = "list1", method = RequestMethod.GET) public String getAllUsingModelAttribute() { logger.debug("Received request to show all addresses page"); // 他会解析 /WEB-INF/jsp/addressespage.jsp return "addressespage"; } /** * 处理和检索一个包含addresses 的JSP Page . * * @return the name of the JSP page */ @RequestMapping(value = "list2", method = RequestMethod.GET) public String getAllUsingModel(Model model) { logger.debug("Received request to show all addresses page"); // 检索所有的address并装入model返回addressespage.jsp model.addAttribute("addresses", addressService.getAll()); model.addAttribute("greetings", "I came from Model not ModelAttribute"); // This will resolve to /WEB-INF/jsp/addressespage.jsp return "addressespage"; }
则访问
http://localhost:8080/spring-jsp/address/list1
时,会自动先执行
public List<Address> getAllAddresses() 方法,并且放到
addresses中,交给JSP页面取出
而在http://localhost:8080/spring-jsp/address/list2 中
则只是用
model.addAttribute实现
2) 模式2:method parameter级(即方法里所带的参数)
如果你的方法参数里带有@ModelAttribute的参数.表示从JSP Page传回的参数并自动的转化为java对象
/** * 检索修改页面 */ @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET) public String getEdit(@PathVariable Integer id, Model model) { /* * @PathVariable表示指定@RequestMapping的URL模板中{}里的值 * 相当于以前我们URL后面传的参数如XX?id=XXXX . * 但是现在我们可以用 XX/id/XX来代替. * 这个就是REST风格的URL,我们可以实现非常复杂的URL模板 */ logger.debug("Received request to show edit page"); /* * 根据ID检索出对应的Person,然后把检索出来的Person放入一个叫 * "personAttribute"的model中. * 这样editpage.jsp就会接收一个 名为personAttribute的参数. * 相当于request.setAttribute("XX",XX) */ model.addAttribute("personAttribute", personService.get(id)); // This will resolve to /WEB-INF/jsp/editpage.jsp return "editpage"; } /** * 保存修改结果 */ @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST) public String saveEdit(@ModelAttribute("personAttribute") Person person, @PathVariable Integer id, Model model) { logger.debug("Received request to update person"); // 我们从页面接收到了一个名为"personAttribute"的model并命名为person // 同样我们也获得了指定的id. person.setId(id); // 更新person personService.edit(person); // 在更新后我们重新显示所有Person 的页面 model.addAttribute("persons", personService.getAll()); // This will resolve to /WEB-INF/jsp/personspage.jsp return "personspage"; }
对于前端的页面JSP
编辑个人信息的页面:
<form:form modelAttribute="personAttribute" method="POST" action="${saveUrl}"> <table> <tr> <td><form:label path="id">Id:</form:label></td> <td><form:input path="id" disabled="true"/></td> </tr>
所以说,在参数中,加了@modelattributes后,
public String saveEdit(@ModelAttribute("personAttribute") Person person,
@PathVariable Integer id, Model model) {
中 表示从JSP 页面返回的一个叫"personAttribute"的值.并自动的转化为Person对象.
3 其他
匿名绑定命令参数
public String test4(@ModelAttribute UserModel user, Model model)
或
public String test5(UserModel user, Model model)
此时我们没有为命令对象提供暴露到模型数据中的名字,此时的名字是什么呢?Spring Web MVC自动将简单类名(首字母小写)作为名字暴露,如“cn.javass.chapter6.model.UserModel”暴露的名字为“userModel”。
public @ModelAttribute List<String> test6()
或
public @ModelAttribute List<UserModel> test7()
对于集合类型(Collection接口的实现者们,包括数组),生成的模型对象属性名为“简单类名(首字母小写)”+“List”,如List<String>生成的模型对象属性名为“stringList”,List<UserModel>生成的模型对象属性名为“userModelList”。
其他情况一律都是使用简单类名(首字母小写)作为模型对象属性名,如Map<String, UserModel>类型的模型对象属性名为“map”。
@ModelAttribute public Account addAccount(@RequestParam String number) { return accountManager.findAccount(number); }
这种情况,model属性的名称没有指定,它由返回类型隐含表示,如这个方法返回Account类型,那么这个model属性的名称是account。
这个例子中model属性名称有返回对象类型隐含表示,model属性对象就是方法的返回值。它无须要特定的参数。