为什么在HttpSessionListener中调用invalidate()并不能给出StackOverflowError?

时间:2018-02-14 15:57:31

标签: java java-ee listener stack-overflow httpsession

我有jsp个文件和HttpSessionListener来监控HttpSession销毁活动。

的index.jsp

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

SessionListener

@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 。但是我得到了以下输出没有任何错误。

ansible-vault encrypt_string 'abc123' --name ansible_ssh_pass > inventory/group_vars/all.yml

我已经使用GlassFish和Tomcat服务器测试过,结果保持不变。有人可以解释一下发生了什么吗?

1 个答案:

答案 0 :(得分:1)

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

在这种情况下,

Session.beginInvalidate()返回false值,并且不会调用此块:

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的{​​{1}}。

因此,如果会话已经失效,则此方案无效。