How can I expire all my sessions in Tomcat?

前端 未结 3 1668
离开以前
离开以前 2020-12-30 10:03

I would like to expire all my sessions in Tomcat. We test our product under Fitnesse and some sessions remain and the end of the session causes dependency between the tests.

3条回答
  •  难免孤独
    2020-12-30 10:15

    I'm assuming your applications are really independent contexts. I have done something similar to what you are asking using an HttpSessionListener for every context. The tricky part here is that you need to have a Session Collection that is loaded by the root class loader as opposed to the context class loader. This is how I remember it:

    Create a class which holds the active sessions for each context. This class must reside in the tomcat /lib directory so that it becomes accessible by every context. It can't be part of any of the contexts.

    public class SessionMap {
    
      private static Map> map =
        new HashMap>();
    
      private SessionMap() {
      }
    
      public static Map> getInstance() {
        return map;
      }
    
      public static void invalidate(String[] contexts) {
        synchronized (map) {
          List l = Arrays.asList(contexts);     
          for (Map.Entry> e : map.entrySet()) {
            // context name without the leading slash
            String c = e.getKey().getContextPath().substring(1);
            if (l.contains(c)) {
              for (HttpSession s : e.getValue()) 
                s.invalidate();
            }
          }
        }
      }
    
    }
    

    Create a listener for every context.

    public class ApplicationContextListener implements HttpSessionListener {
    
      public void sessionCreated(HttpSessionEvent event) {
        ConcurrentMap> instance = SessionMap.getInstance();
        synchronized (instance) {
          ServletContext c = event.getSession().getServletContext();
          Set set = instance.get(c);
          if (c == null) {
            set = new HashSet();
            instance.put(c, set);
          }
          set.add(event.getSession());
        }
      }
    
      public void sessionDestroyed(HttpSessionEvent event) {
        ConcurrentMap> instance = SessionMap.getInstance();
        synchronized (map) {
          ServletContext c = event.getSession().getServletContext();
          Set set = instance.get(c);
          if (c != null) {
            set.remove(event.getSession());
          }
        }
      }
    
    }
    

    Registered each listener in the corresponding context's web.xml.

    
      ApplicationContextListener
    
    

    You can then call the following line to invalidate everything from any context.

    SessionMap.invalidate();
    

    I'm synchronizing on the map just to be on the safe side.

提交回复
热议问题