Почему вызов invalidate() в HttpSessionListener не дает StackruError?
У меня есть 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");
}
}
Теперь в соответствии с описанной выше ситуацией, отправка HTTP-запроса index.jsp
должен создать HttpSession
и назовите это invalidate()
метод, тем временем HttpSessionListener
должен ловить то же самое HttpSession
и позвонить invalidate()
еще раз, и этот процесс должен повторяться снова и снова.
Что в конечном итоге должно привести к броску java.lang.StackruError
, Но я получил следующий вывод без каких-либо ошибок.
SID1 : A2751AE9E782A17380415B0078C9ED90
SID2 : A2751AE9E782A17380415B0078C9ED90
Value
Session Destroyed
Я проверил его на серверах GlassFish и Tomcat, результат остался прежним. Может кто-нибудь объяснить, что происходит?
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
который вызывает _sessionListeners.get(i).sessionDestroyed(event);
,
Так что в случае, если сеанс уже признан недействительным, этот сценарий не работает.