Как получить список всех объектов HttpSession в веб-приложении? - PullRequest
49 голосов
/ 22 сентября 2010

Допустим, у меня запущено веб-приложение на основе Java с 0 или более действительными HttpSession объектами, связанными с ним.Я хочу получить доступ к текущему списку действительных HttpSession объектов.Я думал, что мог бы реализовать HttpSessionListener и использовать его для добавления к списку значений идентификатора сеанса, которые хранятся в атрибуте области приложения, но затем я нахожусь на крючке, чтобы обновить список, так как сеансы недействительны икто знает, что еще.

Перед тем, как начать готовить собственное решение, я подумал, что должен задать вопрос:
Предоставляет ли API сервлета некоторые средства для получения доступа к полному списку недействительныхобъекты сеанса?

Я использую Tomcat 6.x в качестве контейнера веб-приложения и библиотеку MyFaces 1.2.x (JSF).

РЕШЕНИЕ
Я следовал подходу, подобному тому, что BalusC обсуждал в этих существующих вопросах:

Я изменилSessionData класс для реализации HttpSessionBindingListener.Когда происходит событие привязки, объект либо добавляет, либо удаляет себя из набора всех SessionData объектов.

@Override
public void valueBound(HttpSessionBindingEvent event) { 
    // Get my custom application-scoped attribute
    ApplicationData applicationData = getApplicationData();
    // Get the set of all SessionData objects and add myself to it
    Set<SessionData> activeSessions = applicationData.getActiveSessions();
    if (!activeSessions.contains(this)) {
        activeSessions.add(this);
    }
}

@Override
public void valueUnbound(HttpSessionBindingEvent event) {
    HttpSession session = event.getSession();
    ApplicationData applicationData = getApplicationData();
    Set<SessionData> activeSessions = applicationData.getActiveSessions();
    if (activeSessions.contains(this)) {
        activeSessions.remove(this);
    }
}

Единственное, что продолжает раздражать меня, - это то, что происходит при перезапуске Tomcat.Если Tomcat не настроен должным образом, чтобы НЕ сериализовать сеансы на диск, он это сделает.Когда Tomcat запускается снова, объекты HttpSession (и объекты SessionData вместе с ними) десериализуются, и сеансы снова становятся действительными.Однако сериализация / десериализация полностью обходит события прослушивателя HttpSession, поэтому у меня нет возможности изящно поместить десериализованную ссылку на SessionData обратно в мой управляемый набор объектов после перезапуска.

У меня нет контроля над производственной конфигурацией Tomcat в организации моего клиента, поэтому я не могу предположить, что это будет сделано так, как я ожидаю.

Мой обходной путь - сравнить время создания HttpSessionсо временем запуска приложения при получении запроса.Если сеанс был создан до времени запуска приложения, я звоню invalidate(), и пользователь отправляется на страницу ошибки / предупреждения с объяснением того, что произошло.

Я получаю время запуска приложения, реализовавServletContextListener и сохранение текущего времени внутри объекта в области приложения из метода contextInitialized() моего слушателя.

Ответы [ 3 ]

45 голосов
/ 22 сентября 2010

Нет, Servlet API не предоставляет способ.Вы действительно должны схватить их всех с помощью HttpSessionListener.Вы можете найти несколько примеров в следующих ответах:

9 голосов
/ 24 сентября 2010

Прямого пути нет. Это зависит от развертывания. Выше произойдет сбой, как только вы решите ввести распределенное развертывание и распределение нагрузки.

1 голос
/ 07 декабря 2015

Не совсем ответ, но в старые добрые времена был "javax.servlet.http.HttpSessionContext", но он был удален с версии 2.1, явно без замены: https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpSessionContext.html

...