如何使Tomcat中的所有会话失效?

我想在Tomcat中使所有会话失效。 我们在Fitnesse下测试我们的产品,并且一些会话仍然存在,并且会话结束导致测试之间的依赖性。 我使用以下代码手动完成,但仍保留一些会话(我可以使用http:// localhost:8080 / manager / html / list url进行检查)

public static void expireAllSessions() { String[] applications = { "a", "b", "c", "d", "e" }; for (String application : applications) { try { expireAllSessions(application); } catch (Exception e) { logger.error(e); } } } private static void expireAllSessions(final String application) throws Exception { // cf doc http://hc.apache.org/httpclient-3.x/authentication.html HttpClient client = new HttpClient(); client.getParams().setAuthenticationPreemptive(true); Credentials userPassword = new UsernamePasswordCredentials("tomcat", "tomcat"); client.getState().setCredentials(AuthScope.ANY, userPassword); String url = "http://localhost:8080/manager/html/expire"; NameValuePair[] parametres = new NameValuePair[] { new NameValuePair("path", "/" + application), new NameValuePair("idle", "0") }; HttpMethod method = new GetMethod(url); method.setQueryString(parametres); client.executeMethod(method); } 

有没有办法在没有剩余会话的情况下更高效,更直接地做到这一点?

我假设您的应用程序确实是独立的上下文。 我已经做了类似于你要求的每个上下文使用HttpSessionListener东西。 这里棘手的部分是你需要一个由根类加载器加载的Session Collection,而不是上下文类加载器。 这就是我记忆中的方式:

创建一个包含每个上下文的活动会话的类。 此类必须驻留在tomcat / lib目录中,以便每个上下文都可以访问它。 它不能成为任何环境的一部分。

 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(); } } } } } 

为每个上下文创建一个监听器。

 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()); } } } } 

在相应的上下文的web.xml注册每个侦听器。

  ApplicationContextListener  

然后,您可以调用以下行以使任何上下文中的所有内容无效。

 SessionMap.invalidate(); 

我在地图上同步只是为了安全起见。

您可以使用HttpSessionListener来保存对数据结构中会话的引用,然后在闲暇时使用它

你看过Lamda Probe吗? 对于每个Web应用程序,您都可以查看会话的内容并使其过期(全部)。

替代文字

如果你热衷于编写自己的应用程序来做这件事; Lamda Probe是开源的,因此您可以从中获取代码以帮助您实现目标。