首页 | 源码下载 | 网站模板 | 网页特效 | 广告代码 | 网页素材 | 字体下载 | 书库 | 站长工具
会员投稿 投稿指南 RSS订阅
当前位置:主页>网络编程>java教程>资讯:Spring2.5访问Session属性的四种策略

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

www.jz123.cn  2010-03-05   来源:   中国建站    责任编辑(袁袁)    我要投递新闻

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

  还是回到购物车的例子,假设在 controller 某个方法(本文简称为action)中我们要从HttpSession中取到user对象。如果基于Servlet,标准的代码会是这样的:

  Java代码


 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 对象,来让容器注入相应的对象。

  action 的代码如下:

  Java代码


 @RequestMapping
  public void hello(HttpSession session){
  User user = (User)session.getAttribute("currentUser");
  //...
  }

  优点:

  1. 程序中直接得到底层的 Request/HttpSession 对象,直接使用 Servlet API 规范中定义的方法操作这些对象中的属性,直接而简单。

  2. action 需要访问哪些具体的 Session 属性,是由自己控制的,真正精确到 Session 中的每个特定属性。

  不足:

  1. 程序对 Servlet API 产生依赖。虽然 controller 类已经不需要从 HttpServlet 继承,但仍需要 Servlet API 才能完成编译运行,乃至测试。

  2. 暴露了底层 Servlet API,暴露了很多并不需要的底层方法和类,开发人员容易滥用这些 API。

  (二)通过定制拦截器(Interceptor)在controller类级别注入需要的User对象

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

  此外还需要给这些特定 controller 声明一类 interface,比如 IUserAware。这样开发人员就可以只针对这些需要注入 User 对象的 controller 进行注入增强。

  IUserAware 的代码:

  Java代码


 public interface IUserAware {
  public void setUser();
  }

  controller 的代码:

  Java代码


 @Controller
  public GreetingController implements IUserAware {
  private User user;
  public void setUser(User user){
  this.user = user;
  }
  @RequestMapping
  public void hello(){
  //user.sayHello();
  }
  //...
  }

上一篇:Java base64 编码和解码案例 下一篇:Servlet、JSP、EJB该如何抉择

评论总数:0 [ 查看全部 ] 网友评论


关于我们隐私版权广告服务友情链接联系我们网站地图