Jim*_*ugh 49 java servlets web-applications httpsession
假设我有一个运行的基于Java的Web应用程序,其中包含0个或更多HttpSession与之关联的有效对象.我想要一种方法来访问当前的有效HttpSession对象列表.我在想我可以实现一个HttpSessionListener并使用它来追加存储在应用程序范围的属性中的会话ID值列表,但随后会因会话失效而更新列表并且谁知道是什么其他.
在我开始烘焙自己的解决方案之前,我想我应该问一个问题:
servlet API是否提供了一些访问完整的非失效会话对象列表的方法?
我使用Tomcat 6.x作为我的Web应用程序容器和MyFaces 1.2.x(JSF)库.
解决方案
 
我遵循类似于BalusC在这些现有问题中讨论的方法:
我按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已正确配置为不将会话序列化到磁盘,否则它将执行此操作.当Tomcat再次启动时,HttpSession对象(以及SessionData它们与对象一起)被反序列化,会话再次生效.但是,序列化/反序列化完全避开了HttpSession侦听器事件,因此我没有机会SessionData在重新启动后优雅地将反序列化引用放在我的托管对象集中的后面.
我对客户组织中Tomcat的生产配置没有任何控制权,所以我不能假设它会以我期望的方式完成.
我的解决方法是将HttpSession创建时间与收到请求时的应用程序启动时间进行比较.如果会话是在应用程序启动时间之前创建的,那么我会调用invalidate()并将用户发送到错误/警告页面,并说明发生了什么.
我通过在侦听器ServletContextListener的contextInitialized()方法中实现并将当前时间存储在应用程序范围的对象中来获取应用程序启动时间.
| 归档时间: | 
 | 
| 查看次数: | 70361 次 | 
| 最近记录: |