2010年3月25日星期四

[精品]Spring MVC的深入学习一


一 SessionAttribute

         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));     }     … }

没有评论: