Как получить список всех объектов HttpSession в веб-приложении?

Скажем, у меня есть запущенное веб-приложение на основе 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() моего слушателя.

Ответ 1

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

Ответ 2

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