为什么sessionDestroyed()
仅在无效或超时时调用,但在服务器终止时不调用?当服务器终止时,如何在每个会话上进行一些操作?
答案 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.contextDestroyed
和Servlet.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