How can I expire all my sessions in Tomcat?

怎甘沉沦 提交于 2019-11-30 09:11:04

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<ServletContext, Set<HttpSession>> map =
    new HashMap<ServletContext, Set<HttpSession>>();

  private SessionMap() {
  }

  public static Map<ServletContext, Set<HttpSession>> getInstance() {
    return map;
  }

  public static void invalidate(String[] contexts) {
    synchronized (map) {
      List<String> l = Arrays.asList(contexts);     
      for (Map.Entry<ServletContext, Set<HttpSession>> 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<ServletContext, Set<HttpSession>> instance = SessionMap.getInstance();
    synchronized (instance) {
      ServletContext c = event.getSession().getServletContext();
      Set<HttpSession> set = instance.get(c);
      if (c == null) {
        set = new HashSet<HttpSession>();
        instance.put(c, set);
      }
      set.add(event.getSession());
    }
  }

  public void sessionDestroyed(HttpSessionEvent event) {
    ConcurrentMap<ServletContext, Set<HttpSession>> instance = SessionMap.getInstance();
    synchronized (map) {
      ServletContext c = event.getSession().getServletContext();
      Set<HttpSession> set = instance.get(c);
      if (c != null) {
        set.remove(event.getSession());
      }
    }
  }

}

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

<listener>
  <listener-class>ApplicationContextListener</listener-class>
</listener>

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.

You could use HttpSessionListener to save the references to sessions in a data structure and then use it at your leisure

Have you looked at Lamda Probe? For each of your web applications, you can view the contents of the session and expire them (all).

If you are keen on writing your own app to do this instead; Lamda Probe is open source, so you could take code from them to help accomplish your goal.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!