Почему вызов 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);,

Так что в случае, если сеанс уже признан недействительным, этот сценарий не работает.

Другие вопросы по тегам