Как получить доступ к сеансам HTTP в Java - PullRequest
6 голосов
/ 13 июля 2010

Как элегантно получить любой http-сеанс по id или всем активным в данный момент http-сеансам в веб-приложении (Java 2 EE)?

В настоящее время у меня есть WebSessionListener, и после создания сеанса я помещаю его в ConcurrentHashMap() (map.put(sessionId, sessionObj)), все в порядке, я могу в любой момент получить HTTP-сеанс из этой карты по идентификатору сеанса, но он выглядит как объекты HttpSession никогда не будет завершен ... Даже сеанс был признан недействительным, карта все еще ссылается на недействительный объект сеанса ... Также я прочитал эту статью , и похоже, что WeakHashMap неприемлемо в моем случае ...

Другими словами, мне нужна возможность просмотреть в любой HttpSession даже получить все активные в данный момент HttpSession и получить оттуда некоторые атрибуты ...

Пожалуйста, посоветуйте кому-нибудь:)

Обновление

Мне нужен доступ к объектам HttpSession по следующей причине:

Иногда пользователь выполняет некоторые действия / запросы, которые могут повлиять на работу другого параллельного пользователя, например, администратор должен отключить учетную запись пользователя, но этот пользователь в настоящее время работает с системой, в этом случае мне нужно показать сообщение администратору, например, «Пользователь XXX в настоящее время работает с системой», поэтому мне нужно проверить, существует ли и активен ли любой HttpSession, который содержит учетные данные пользователя XXX. Вот почему мне нужна такая возможность, чтобы получить любой http-сеанс или даже все сеансы.

Моя текущая реализация: SessionManager, который знает обо всех сеансах (ConcurrentMap), и HttpSessionListener, которые помещают / удаляют сеанс в SessionManager.

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

Большое спасибо за ваши повторы, но теперь я понял, что проблема была только в воображении:)

Ответы [ 3 ]

7 голосов
/ 13 июля 2010

Согласно вашему разъяснению:

Иногда пользователь выполняет некоторые действия / запросы, которые могут повлиять на работу другого параллельного пользователя, например, администратор должен отключить учетную запись пользователя, но этот пользователь в настоящее время работает ссистема, в этом случае мне нужно показать сообщение администратору, например, «пользователь XXX в настоящее время работает с системой», поэтому мне нужно проверить, существует ли и активен ли любой HttpSession, который содержит учетные данные пользователя XXX.Вот почему мне нужна такая возможность получить любой сеанс http или даже все сеансы.

Для этого вам вообще не нужно ничего знать о сеансах.Вам просто нужно знать, какие пользователи вошли в систему. Для этого вы можете прекрасно позволить объекту модели, представляющему собой зарегистрированного пользователя внедрить HttpSessionBindingListener.Я, конечно, предполагаю, что вы следуете обычному идиому входа / выхода из системы, устанавливая / удаляя модель User в качестве атрибута сеанса.

public class User implements HttpSessionBindingListener {

    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        Set<User> logins = (Set<User>) event.getSession().getServletContext().getAttribute("logins");
        logins.add(this);
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        Set<User> logins = (Set<User>) event.getSession().getServletContext().getAttribute("logins");
        logins.remove(this);
    }

    // @Override equals() and hashCode() as well!

}

Затем где-нибудь в вашем приложении администратора просто получителогины от ServletContext:

Set<User> logins = (Set<User>) servletContext.getAttribute("logins");
5 голосов
/ 13 июля 2010

Вообще говоря, ваш контейнер сервлетов будет иметь свой собственный менеджер сеансов, который отвечает как за поддержание жизненного цикла сеансов, так и за привязку входящих запросов к соответствующему сеансу (через файлы cookie, параметры привязки, любую стратегию, которую он хочет).1001 *

Элегантный способ сделать это - подключиться к этому менеджеру сеансов любым доступным способом.Вы можете создать подкласс по умолчанию, например, чтобы получить доступ к произвольным сеансам.

Однако, похоже, то, что вы делаете, противоречит основной проблеме вашей архитектуры.Данные, содержащиеся в сеансе, должны быть специфичными для этого сеанса, поэтому в общем случае вам не нужно искать произвольные данные для обеспечения стандартной логики вашего веб-приложения.А административные / хозяйственные задачи обычно выполняются для вас контейнером, поэтому вам не нужно вмешиваться в это.

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

4 голосов
/ 13 июля 2010

Анджей Дойл очень прав. Но если вы действительно, действительно хотите управлять своим собственным списком сеансов, то способ подключения к вашему контейнеру - через HttpSessionListener - пример кода .

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

Вы используете web.xml для регистрации прослушивателя сеанса в качестве прослушивателя жизненного цикла для вашего приложения.

Вы можете связать свой список сеансов с другими процессами в контейнере, используя ServletContext, или вы можете создать более грязную схему, например, с помощью. поля статического класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...