Spring 允许我们有选择地指定 ModelMap 中的哪些属性需要转存到 session 中,以便下一个请求属对应的 ModelMap 的属性列表中还能访问到这些属性。这一功能是通过类定义处标注 @SessionAttributes 注解来实现的。
使用方法:
@Controller @RequestMapping("/bbtForum.do") @SessionAttributes("currUser") //①将ModelMap中属性名为currUser的属性 //放到Session属性列表中,以便这个属性可以跨请求访问 public class BbtForumController { … @RequestMapping(params = "method=listBoardTopic") public String listBoardTopic(@RequestParam("id")int topicId, User user, ModelMap model) { bbtForumService.getBoardTopics(topicId); System.out.println("topicId:" + topicId); System.out.println("user:" + user); model.addAttribute("currUser",user); //②向ModelMap中添加一个属性 return "listTopic"; } }
二 ModelAttribute
上面讲述了如何往ModelMap中放置属性以及如何使ModelMap中的属性拥有Session域的作用范围。除了在JSP视图页面中通过传统的方法访问ModelMap中的属性外,Spring提供了一个@ModelAttribute的注解可以将ModelMap中的属性绑定到请求处理方法的入参中,他还可以与jsp标签<form:form modelAttribute="entity"></form:form>一起使用。
总结它的作用:
- 将多个参数绑定到一个Bean中;
- 自动将Bean值add到Model中,相当于进行了Model.addAttribute("key",bean);这样可以在jsp中使用EL表达式或是传统的jsp表达式访问bean;
- 与jsp标签<form:form modelAttribute="entity"></form:form>一起使用,直接将bean的各个域对应到form标签的子标签(如<form:input path="field"/>,只需要将域的值设置为path值)直接显示在页面上。
- 在方法之上使用,使方法的返回值被add到Model中,这个方法会被所有此类中的请求方法被调用时使用。所以所有的请求的model中都会有这个Attribute存在。
使用方法:
@Controller @RequestMapping("/bbtForum.do") @SessionAttributes("currUser") //①让ModelMap的currUser属性拥有session级作用域 public class BbtForumController { @Autowired private BbtForumService bbtForumService; @RequestMapping(params = "method=listBoardTopic") public String listBoardTopic(@RequestParam("id")int topicId, User user, ModelMap model) { bbtForumService.getBoardTopics(topicId); System.out.println("topicId:" + topicId); System.out.println("user:" + user); model.addAttribute("currUser",user); //②向ModelMap中添加一个属性 return "listTopic"; }
@RequestMapping(params = "method=listAllBoard") //③将ModelMap中的 public String listAllBoard(@ModelAttribute("currUser") User user) { //currUser属性绑定到user入参中。 bbtForumService.getAllBoard(); System.out.println("user:"+user); return "listBoard"; } }
在 ② 处,我们向 ModelMap 中添加一个名为 currUser 的属性,而 ① 外的注解使这个 currUser 属性拥有了 session 级的作用域。所以,我们可以在 ③ 处通过 @ModelAttribute 注解将 ModelMap 中的 currUser 属性绑定以请求处理方法的 user 入参中。
所以当我们先调用以下 URL 请求: http://localhost/bbtForum.do?method=listBoardTopic&id=1&userName=tom&dept.deptId=12
以执行listBoardTopic()请求处理方法,然后再访问以下URL: http://localhost/sample/bbtForum.do?method=listAllBoard
你将可以看到 listAllBoard() 的 user 入参已经成功绑定到 listBoardTopic() 中注册的 session 级的 currUser 属性上了。
在方法级上使用ModelAttribute:
@Controller @RequestMapping("/bbtForum.do") public class BbtForumController { @Autowired private BbtForumService bbtForumService; @ModelAttribute("items")//<——①向模型对象中添加一个名为items的属性 public List<String> populateItems() { List<String> lists = new ArrayList<String>(); lists.add("item1"); lists.add("item2"); return lists; } @RequestMapping(params = "method=listAllBoard") public String listAllBoard(@ModelAttribute("currUser")User user, ModelMap model) { bbtForumService.getAllBoard(); //<——②在此访问模型中的items属性 System.out.println("model.items:" + ((List<String>)model.get("items")).size()); return "listBoard"; } }
三 注册自己的属性编辑器
- 注册框架级的自定义属性编辑器
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="webBindingInitializer"> <bean class="com.baobaotao.web.MyBindingInitializer"/> </property> </bean>
MyBindingInitializer是继承自 WebBindingInitializer的类,如下:
public class MyBindingInitializer implements WebBindingInitializer { public void initBinder(WebDataBinder binder, WebRequest request) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); dateFormat.setLenient(false); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); binder.registerCustomEditor(String.class, new StringTrimmerEditor(false)); } }
- 注册 Controller 级的自定义属性编辑器
如果希望某个属性编辑器仅作用于特定的 Controller,可以在 Controller 中定义一个标注 @InitBinder 注解的方法,可以在该方法中向 Controller 了注册若干个属性编辑器,来看下面的代码:
@Controller public class MyFormController { @InitBinder public void initBinder(WebDataBinder binder) { //必须有WebDataBinder类型的参数 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); dateFormat.setLenient(false); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); } … }
没有评论:
发表评论