Java 为什么在HttpSessionListener中调用invalidate()不';不要给StackOverflower错误?
我有一个Java 为什么在HttpSessionListener中调用invalidate()不';不要给StackOverflower错误?,java,jakarta-ee,listener,stack-overflow,httpsession,Java,Jakarta 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(); %> 现在根据上述情况,向index.jsp发送HTTP请求应该创建一
jsp
文件和一个HttpSessionListener
来监视HttpSession
销毁活动
index.jsp
<%
HttpSession s = request.getSession();
System.out.println("SID1 : " + s.getId());
s.setAttribute("Key", "Value");
s.invalidate();
%>
现在根据上述情况,向index.jsp
发送HTTP请求应该创建一个HttpSession
并调用它的invalidate()
方法,同时HttpSessionListener
应该捕获相同的HttpSession
并再次调用invalidate()
,这个过程应该一次又一次地重复
这最终会导致抛出一个java.lang.StackOverflowerError
。但是我得到了以下输出,没有任何错误。
SID1 : A2751AE9E782A17380415B0078C9ED90
SID2 : A2751AE9E782A17380415B0078C9ED90
Value
Session Destroyed
我已经用GlassFish和Tomcat服务器对其进行了测试,结果保持不变。有人能解释发生了什么吗?显然,这是因为当您从
public void sessionDestroyed(HttpSessionEvent se){…}
第二次调用invalidate
方法时,会话已经失效
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());
}
}
特别是,\u handler.getSessionIdManager().invalidateAll
调用SessionHandler.invalidate
,调用SessionHandler.removeSession
,调用\u sessionListeners.get(i).sessionDestroyed(事件)代码>
因此,如果会话已无效,则此场景不起作用。为什么要抛出StackOverflowerError
?HttpSession.invalidate()上的函数提到,如果在已经失效的会话上调用此方法,则它应该抛出IllegalStateException
。这可能是您正在使用的特定应用程序服务器的一个怪癖/错误。能否在jsp中的s.invalidate()之后打印request.getSession().isNew(),并告诉我们结果?会话不会在第一次失效。看看会话ID。它们是一样的。所以它应该不断地调用invalidateagain@techtrainer在jsp
文件中?在jsp文件中是的,如注释中所述。如果会话已经无效,那么在侦听器中调用时,属性如何在输出中打印出来?我不理解您的最后一个问题。有什么问题吗?第一次调用s.invalidate()代码>来自JSP。它完成了我在回答中描述的所有顺序。之后,将在执行所有打印输出的位置调用您的sessionDestroyed
。然后再次调用那里的s.invalidate()
,但它没有效果,因为此时会话已经无效。
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());
}
}