Как получить доступ к Сеансам HTTP в Java

Как получить какой-либо сеанс HTTP идентификатором или все в настоящее время активные сеансы HTTP в рамках веб-приложения (Java 2 EE) изящным способом?

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

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

Совет кто-то :)

Обновление

Я должен получить доступ к объектам HttpSession из-за причины follwoing:

Иногда пользователь делает некоторые действия/запросы, которые могут повлиять на работу другого параллельного пользователя, например, администратор должен отключить учетную запись пользователя, но этот пользователь, в настоящее время работающий с системой, в этом случае, я должен показать, что сообщение администратору, например, "пользователю XXX в настоящее время работает с системой", следовательно я должен проверить, существует ли какой-либо HttpSession, который содержит учетные данные пользователя XXX уже, и активный. Таким образом, это - whay, мне нужна такая возможность получить любой сеанс HTTP или даже все сессии.

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

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

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

6
задан Gordon 13 March 2013 в 09:46
поделиться

3 ответа

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

Иногда пользователь выполняет некоторые действия / запросы, которые могут повлиять на работу другого одновременно работающего пользователя, например, администратор должен отключить учетную запись пользователя, но этот пользователь в настоящее время работает с системой , в этом случае мне нужно показать сообщение администратору, например «пользователь 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");
7
ответ дан 8 December 2019 в 14:39
поделиться

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

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

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

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

5
ответ дан 8 December 2019 в 14:39
поделиться

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

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

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

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

4
ответ дан 8 December 2019 в 14:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: