Spring2.5 访问 Session 属性的四种策略

http://www.blogjava.net/mingj/archive/2008/10/12/233871.html
WEB 应用通常会引入 Session,用来在服务端和客户端之间保存一系列动作/消息的状态,比如网上购物维护 user 登录信息直到 user 退出。在 user 登录后,Session 周期里有很多 action 都需要从 Session 中得到 user,再验证身份权限,或者进行其他的操作。这其中就会涉及到程序去访问 Session属性的问题。在java中,Servlet 规范提供了 HttpSession对象来满足这种需求。开发人员可以从 HttpServletRquest对象得到 HttpSession,再从HttpSession中得到状态信息。

还是回到购物车的例子,假设在 controller 某个方法(本文简称为action)中我们要从HttpSession中取到user对象。如果基于Servlet,标准的代码会是这样的:
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 User user = (User)req.getSession().getAttribute("currentUser");
 //
}

这样的代码在传统的Servlet程序中是很常见的:因为使用了 Servlet API,从而对 Servlet API产生依赖。这样如果我们要测试 action,我们就必须针对 HttpServletRequest、HttpServletResponse 和 HttpSession类提供 mock 或者 stub 实现。当然现在已经有很多开源的 Servlet 测试框架帮助我们减轻这个痛苦,包括 Spring 就自带了对了这些类的 stub 实现,但那还是太冗繁琐碎了。那有没有比较好的办法来让我们的 controller 更 POJO,让我们的 action 脱离 Servlet API 依赖,更有益于测试和复用呢?我们来看看在 Spring2.5 中访问 Session 属性的几种策略,并将在本博的后续文章继续探究解决方案选择后面的深层含义。


(一)通过方法参数传入HttpServletRequest对象或者HttpSession对象
笔者的前一篇文章已经简单介绍了Spring2.5的annotation使得 controller 摆脱了 Servlet API 对方法参数的限制,这里就不赘述了。有兴趣的同学可以参考这里。 Spring对annotationed的 action 的参数提供自动绑定支持的参数类型包括 Servlet API 里面的 Request/Response/HttpSession(包含Request、Response在Servlet API 中声明的具体子类)。于是开发人员可以通过在 action 参数中声明 Request 对象或者 HttpSession 对象,来让容器注入相应的对象。
@RequestMapping
public void hello(HttpSession session){
 User user = (User)session.getAttribute("currentUser");
 //......
}


(二)通过定制拦截器(Interceptor)在controller类级别注入需要的User对象
Interceptor 是 Spring 提供的扩展点之一,SpringMVC 会在 handle 某个 request 前后调用在配置中定义的 Interceptor 完成一些切面的工作,比如验证用户权限、处理分发等,类似于 AOP。那么,我们可以提取这样一个“横切点”,在 SpringMVC 调用 action 前,在 Interceptor 的 preHandle 方法中给 controller 注入 User 成员变量,使之具有当前登录的 User 对象。

(三)通过方法参数处理类(MethodArgumentResolver)在方法级别注入User对象
正如前面所看到的,SpringMVC 提供了不少扩展点给开发人员扩展,让开发人员可以按需索取,plugin 上自定义的类或 handler。那么,在 controller 类的层次上,SpringMVC 提供了 Interceptor 扩展,在 action 上有没有提供相应的 handler 呢?如果我们能够对 action 实现注入,出现的种种不足了。

四)通过 SpringMVC 的 SessionAttributes Annotation 关联 User 属性
SpringMVC 文档提到了 @SessionAttributes annotation,和 @ModelAttribute 配合使用可以往 Session 中存或者从 Session 中取指定属性名的具体对象。文档里说;

猜你喜欢

转载自panyongzheng.iteye.com/blog/1230988
今日推荐