如何获取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几个例子:
- 如何通过jsessionidfind
HttpSession
? - 如何查找每个IP的活动会话数量?
- 如何检查谁在线?
- 当用户login两次时如何使另一个会话失效?
没有简单的方法。 这取决于部署。 一旦决定引入分布式部署和负载平衡,以上将会失败。
不是一个真正的答案,但在良好的日子里有“javax.servlet.http.HttpSessionContext”,但是从版本2.1被删除,显式地没有replace: https : //tomcat.apache.org/tomcat- 5.5-DOC / servletapi /的javax / servlet的/ HTTP / HttpSessionContext.html