在服务器终止时调用会话Destroyed()

时间:2012-08-28 17:55:15

标签: java tomcat servlets servlet-listeners

为什么sessionDestroyed()仅在无效或超时时调用,但在服务器终止时不调用?当服务器终止时,如何在每个会话上进行一些操作?

3 个答案:

答案 0 :(得分:5)

Java Servlet 3.0规范声明应在服务器/应用程序关闭时调用HttpSessionListener.sessionDestroyed()(第11.3.4节关闭时通知):

  

在应用程序关闭时,将以与其声明相反的顺序通知侦听器   在向上下文侦听器发出通知之前向会话侦听器发送通知。   必须在上下文侦听器之前通知会话侦听器会话失效   被通知应用程序关闭。

Tomcat 7实现了Java Servlet 3.0规范,应该支持您的用例。

答案 1 :(得分:2)

关于您的第一个问题:

  

为什么sessionDestroyed()仅在无效或超时时调用,而在服务器终止时不调用?

以下解释了为什么在Tomcat中关闭时(至少从Tomcat 6.0.33开始)调用时sessionDestroyed()未被调用,来自Tomcat上的帖子:http://comments.gmane.org/gmane.comp.jakarta.tomcat.user/215644

  

当我申请我的网络应用程序时,我收到sessionCreated,当我   从我收到sessionDestroyed的代码中使会话无效。   不幸的是,当我停止Web应用程序时,我没有收到   sessionDestroyed。

     

我检查了StandardContext停止的代码。我知道   调用StandardManager.stop即可   但是当调用StandardManager.doUnload()时,在其实现中*   调用session.expire(false)*,其中“false”实际上是标志   指示是否通知听众。因为它被调用   “false” - 不调用侦听器。

这不是我的帖子,我将此归功于该职位的作者Violeta。

该帖子提供了修补StandardManager.java的方法。

如果您不想修改该类(我个人会尽可能避免修改属于Application Server的类),您可以采取其他方法。

关于你的第二个问题:

  

如何在服务器终止时对每个会话进行一些操作?

为什么要在服务器终止时对每个会话执行操作? Servlet规范提供了在服务器关闭时执行代码的方法。但是,它们不提供可以对每个活动会话执行操作的方法(可能是通过设计)。

正如前面的回答提到的那样,How to access HTTP sessions in Java,会话管理应由Servlet容器处理,您可以重新考虑当前的应用程序方法。

对于服务器关闭时的常规处理清理,您有ServletContextListener.contextDestroyedServlet.destroy

ServletContextListener界面提供contextDestroyed生命周期方法

Servlet接口提供了一个destroy方法,用于在服务器关闭时释放任何资源或处理任何清理。

答案 2 :(得分:2)

阅读Execute code after Glassfish Web Deployment我得到了这个问题的答案。

我们能够编写ServletContextListener,以便在加载或终止上下文时触发:

public class MyServlet implements ServletContextListener {

  public void contextInitialized(ServletContextEvent e) {
         // implementation code
  }

  public void contextDestroyed(ServletContextEvent e) {
         // implementation code
  }
}

现在在你的情况下,将关闭一个关闭,然后将调用contextDestroyed()方法。

参考:

感谢Garis Suero