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