为什么在 HttpSessionListener 中调用 invalidate() 不会给出 StackOverflowError?
Why calling invalidate() in HttpSessionListener doesn't give StackOverflowError?
我有一个 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.WhosebugError
。但是我得到了以下输出 ,没有任何错误。
SID1 : A2751AE9E782A17380415B0078C9ED90
SID2 : A2751AE9E782A17380415B0078C9ED90
Value
Session Destroyed
我已经用 GlassFish 和 Tomcat 服务器对其进行了测试,结果保持不变。谁能解释一下这是怎么回事?
显然这是因为当您从 public void sessionDestroyed(HttpSessionEvent se) {...}
.
第二次调用 invalidate
方法时会话已经失效
Session.beginInvalidate()
returns 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
,后者调用 _sessionListeners.get(i).sessionDestroyed(event);
。
因此,如果会话已经失效,则此方案不起作用。
我有一个 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.WhosebugError
。但是我得到了以下输出 ,没有任何错误。
SID1 : A2751AE9E782A17380415B0078C9ED90
SID2 : A2751AE9E782A17380415B0078C9ED90
Value
Session Destroyed
我已经用 GlassFish 和 Tomcat 服务器对其进行了测试,结果保持不变。谁能解释一下这是怎么回事?
显然这是因为当您从 public void sessionDestroyed(HttpSessionEvent se) {...}
.
invalidate
方法时会话已经失效
Session.beginInvalidate()
returns 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
,后者调用 _sessionListeners.get(i).sessionDestroyed(event);
。
因此,如果会话已经失效,则此方案不起作用。