2010-09-22 4 views
48

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

Перед тем, как начать выпечки мое собственное решение, я думал, что я должен задать вопрос:
Предоставляет ли сервлет 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 в организации моего клиента, поэтому я не могу предположить, что это будет сделано так, как я ожидаю.

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

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

ответ

40

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

9

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

+1

Мое приложение будет иметь ограниченное количество пользователей в частной сети, поэтому мне не нужно поддерживать распределенное развертывание. Однако я согласен с вашим комментарием. –

+0

Я предполагаю, что способ изменить это (а также настойчивость на диске) будет состоять в том, чтобы прослушиватель обновил общий хранилище данных (Redis, Memcached или что-то еще), которое отслеживает сеансы. – Thilo

Смежные вопросы