如何获取 Web 应用程序中所有 HttpSession 对象的列表? [英] How do I get a list of all HttpSession objects in a web application?

查看:19
本文介绍了如何获取 Web 应用程序中所有 HttpSession 对象的列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个正在运行的基于 Java 的 Web 应用程序,其中有 0 个或多个与之关联的有效 HttpSession 对象.我想要一种访问当前有效 HttpSession 对象列表的方法.我在想我可以实现一个 HttpSessionListener 并使用它来附加到存储在应用程序范围属性中的会话 id 值列表,但随后我需要更新列表因为会话已失效,谁知道还有什么.

Let's say I have a running Java-based web application with 0 or more valid HttpSession objects associated with it. I want a way to access the current list of valid HttpSession objects. I was thinking that I could implement an HttpSessionListener and use it to append to a list of session id values that are stored in an application-scoped attribute, but then I'm on the hook to update the list as sessions are invalidated and who knows what else.

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

Before I start baking my own solution I thought I should ask the question:
Does the servlet API provide some means of getting access to the complete list of non-invalidated session objects?

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

I am using Tomcat 6.x as my web application container, and the MyFaces 1.2.x (JSF) library.

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

SOLUTION
I followed an approach similar to what BalusC discussed in these existing questions:

我通过SessionData 类修改来实现HttpSessionBindingListener.当绑定事件发生时,该对象将在所有 SessionData 对象的集合中添加或删除它自己.

I modified by SessionData class to implement HttpSessionBindingListener. When a binding event happens, the object will either add or remove itself from the set of all the SessionData objects.

@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 已正确配置为不将会话序列化到磁盘,否则它会这样做.当 Tomcat 再次启动时,HttpSession 对象(以及与它们一起的 SessionData 对象)被反序列化并且会话再次有效.但是,序列化/反序列化完全避开了 HttpSession 侦听器事件,因此我没有机会优雅地将反序列化的对 SessionData 的引用放回我的托管对象集中重启后.

The one thing that continues to irritate me is what happens when Tomcat is restarted. Unless Tomcat has been properly configured to NOT serialize sessions to disk, it will do so. When Tomcat starts up again, the HttpSession objects (and the SessionData objects along with them) are deserialized and the sessions are made valid again. However, the serialization/deserialization totally sidesteps the HttpSession listener events, so I do not have the opportunity to gracefully put the deserialized reference to the SessionData back in my managed Set of objects after the restart.

我无法控制客户组织中 Tomcat 的生产配置,因此我不能假设它会按照我期望的方式完成.

I don't have any control over the production configuration of Tomcat in my customer's organization, so I cannot assume that it will be done the way I expect it.

我的解决方法是将 HttpSession 创建时间与收到请求时的应用程序启动时间进行比较.如果会话是在应用程序启动时间之前创建的,那么我调用 invalidate() 并且用户将被发送到错误/警告页面,并说明所发生的事情.

My workaround is to compare the HttpSession creation time with the application startup time when a request is received. If the session was created before the application startup time, then I call invalidate() and the user is sent to an error/warning page with an explanation of what happened.

我通过实现 ServletContextListener 并将当前时间存储在我的侦听器的 contextInitialized() 方法中的应用程序范围对象中来获取应用程序启动时间.

I get the application startup time by implementing a ServletContextListener and storing the current time inside an application-scoped object from within the contextInitialized() method of my listener.

推荐答案

不,Servlet API 没有提供方法.你真的必须在 HttpSessionListener 的帮助下掌握它们.您可以在以下答案中找到几个示例:

No, the Servlet API doesn't provide a way. You really have to get hold of them all with help of a HttpSessionListener. You can find several examples in the following answers:

  • How to find HttpSession by jsessionid?
  • How to find number of active sessions per IP?
  • How to check Who's Online?
  • How to invalidate another session when a user is logged in twice?

这篇关于如何获取 Web 应用程序中所有 HttpSession 对象的列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆