如何获取Web应用程序中所有HttpSession对象的列表?

比方说,我有一个正在运行的基于Java的Web应用程序,其中有0个或更多有效的HttpSession对象与之关联。 我想要一种方法来访问当前有效的HttpSession对象列表。 我在想,我可以实现一个HttpSessionListener并使用它来追加到存储在应用程序作用域属性中的会话id值列表中,但是随着会话无效,还有什么。

在我开始烘焙自己的解决scheme之前,我想我应该问这个问题:
servlet API是否提供了一些访问非失效会话对象的完整列表的方法?

我使用Tomcat 6.x作为我的Web应用程序容器,以及MyFaces 1.2.x(JSF)库。


我采用了类似于BalusC在这些现有问题中讨论的方法:

  • 如何在Grails或Java应用程序中轻松实现“谁在线”?
  • JSF:如何使用相同凭据login两次时使用户会话失效

我由SessionData类修改来实现HttpSessionBindingListener 。 绑定事件发生时,对象将添加或从所有SessionData对象的集合中删除它自己。

 @Override public void valueBound(HttpSessionBindingEvent event) { // Get my custom application-scoped attribute ApplicationData applicationData = getApplicationData(); // Get the set of all SessionData objects and add myself to it Set<SessionData> activeSessions = applicationData.getActiveSessions(); if (!activeSessions.contains(this)) { activeSessions.add(this); } } @Override public void valueUnbound(HttpSessionBindingEvent event) { HttpSession session = event.getSession(); ApplicationData applicationData = getApplicationData(); Set<SessionData> activeSessions = applicationData.getActiveSessions(); if (activeSessions.contains(this)) { activeSessions.remove(this); } } 

有一件事继续让我感到恼火,那就是Tomcat重启后会发生什么。 除非Tomcat已被正确configuration为不会将会话序列化到磁盘,否则会这样做。 当Tomcat重新启动时, HttpSession对象(以及与它们一起的SessionData对象)被反序列化,并且会话再次生效。 但是,序列化/反序列化完全回避了HttpSession侦听器事件,所以我没有机会在重新启动后正常地将反序列化的SessionData引用SessionData回到我pipe理的对象集中。

我无法控制客户组织中Tomcat的生产configuration,所以我不能认为它会以我期望的方式完成。

我的解决方法是比较HttpSession创build时间和收到请求时的应用程序启动时间。 如果会话是在应用程序启动时间之前创build的,则我调用invalidate() ,并将用户发送到错误/警告页面,并解释发生了什么。

我通过实现ServletContextListener获取应用程序启动时间,并将当前时间存储在侦听器的contextInitialized()方法中的应用程序作用域对象内。

不,Servlet API不提供一种方法。 你真的必须在HttpSessionListener帮助下把握它们。 你可以在下面的答案中find几个例子:

  • 如何通过jsessionidfindHttpSession
  • 如何查找每个IP的活动会话数量?
  • 如何检查谁在线?
  • 当用户login两次时如何使另一个会话失效?

没有简单的方法。 这取决于部署。 一旦决定引入分布式部署和负载平衡,以上将会失败。

不是一个真正的答案,但在良好的日子里有“javax.servlet.http.HttpSessionContext”,但是从版本2.1被删除,显式地没有replace: https : //tomcat.apache.org/tomcat- 5.5-DOC / servletapi /的javax / servlet的/ HTTP / HttpSessionContext.html