java - 为什么在 HttpSessionListener 中调用 invalidate() 不会给出 StackOverflowError?

标签 java jakarta-ee listener stack-overflow httpsession

我有一个 jsp 文件和一个 HttpSessionListener 来监视 HttpSession 破坏 Activity 。

index.jsp

<%
    HttpSession s = request.getSession();
    System.out.println("SID1 : " + s.getId());
    s.setAttribute("Key", "Value");
    s.invalidate();
%>

session 监听器

@WebListener
public class SessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent se) {
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        HttpSession s = se.getSession();
        System.out.println("SID2 : " + s.getId());
        System.out.println(s.getAttribute("Key"));
        s.invalidate();
        System.out.println("Session Destroyed");
    }

}

现在根据上面的情况,向index.jsp发送一个HTTP请求应该创建一个HttpSession并调用它的invalidate()方法,同时 HttpSessionListener 应该捕获相同的 HttpSession 并再次调用 invalidate() ,这个过程应该一遍又一遍地重复。

这最终会导致抛出一个 java.lang.StackOverflowError。但是我得到了以下输出没有任何错误。

SID1 : A2751AE9E782A17380415B0078C9ED90
SID2 : A2751AE9E782A17380415B0078C9ED90
Value
Session Destroyed

我已经用 GlassFish 和 Tomcat 服务器对其进行了测试,结果保持不变。谁能解释一下这是怎么回事?

最佳答案

显然,这是因为当您从 public void sessionDestroyed(HttpSessionEvent se) {...} 第二次调用 invalidate 方法时, session 已经失效。

Session.beginInvalidate() 在这种情况下返回 false 值并且不会调用此 block :

boolean result = beginInvalidate();

try {
    //if the session was not already invalid, or in process of being invalidated, do invalidate
    if (result) {
         //tell id mgr to remove session from all contexts
         _handler.getSessionIdManager().invalidateAll(_sessionData.getId());
    }
}

特别是,_handler.getSessionIdManager().invalidateAll 调用 SessionHandler.invalidate,后者调用 SessionHandler.removeSession,后者调用 _sessionListeners .get(i).sessionDestroyed(event);.

因此,如果 session 已经失效,则此方案不起作用。

关于java - 为什么在 HttpSessionListener 中调用 invalidate() 不会给出 StackOverflowError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48791302/

相关文章:

java - 尝试设计一个函数 : hasCheated(String s1, String s2, int N) 来计算

android - onLongClick 触发 Linkify onClick

java - 在java中的二维字符数组中查找单词。如果某些部分没有被注释掉,为什么我会遇到搜索问题?

java - 如何检测 Map<String,List<String>> 中的重复列表

java - 部署 J2EE Web 应用程序

jakarta-ee - 微服务设计中生成JPA实体

java - 如何验证 JUnit 中静态方法的参数?

Eclipse SWT 中循环组合的 Java 监听器

Python 与 UDP 监听器重叠计时器

Java thread.slee 标准好奇心