Java: отслеживание сеанса входа пользователя в систему - PullRequest
13 голосов
/ 11 мая 2010

Если я хочу отслеживать состояние разговора с каждым клиентом, использующим мое веб-приложение, какой вариант лучше использовать - сессионный компонент или сеанс HTTP?

Использование HTTP-сессии:

//request is a variable of the class javax.servlet.http.HttpServletRequest
//UserState is a POJO
HttpSession session = request.getSession(true);
UserState state = (UserState)(session.getAttribute("UserState"));
if (state == null) { //create default value .. }
String uid = state.getUID();
//now do things with the user id

Использование сеанса EJB:

В реализации ServletContextListener зарегистрирован как слушатель веб-приложения в WEB-INF/web.xml:

//UserState NOT a POJO this this time, it is
//the interface of the UserStateBean Stateful Session EJB
@EJB
private UserState userStateBean;

public void contextInitialized(ServletContextEvent sce) {
    ServletContext servletContext = sce.getServletContext();
    servletContext.setAttribute("UserState", userStateBean);
    ...

В JSP:

public void jspInit() {
    UserState state = (UserState)(getServletContext().getAttribute("UserState"));
    ...
}

В другом месте в теле того же JSP:

String uid = state.getUID();
//now do things with the user id

Мне кажется, что они почти одинаковы, с основным отличием в том, что экземпляр UserState переносится в HttpRequest.HttpSession в первом и в ServletContext в случае последнего.

Какой из двух методов более надежен и почему?

Ответы [ 3 ]

11 голосов
/ 11 мая 2010

Как указал @BalusC, в вашем примере EJB будет одинаковым для всех клиентов - не то, что вы хотите.

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

Но есть и другие более тонкие различия между использованием HttpSession и сессионным компонентом с состоянием (SFSB).Особенно эти два:

  1. Обработка исключений .Если транзакция завершается неудачно в EJB, бин становится недействительным и больше не может использоваться.Это может усложнить стратегию обработки ошибок в веб-приложении.
  2. Параллелизм .Доступ к одной и той же SFSB невозможен одновременно, поэтому вам необходимо синхронизировать ее на веб-уровне.Опять же, это может усложнить проект.

См. Этот ответ для получения более подробной информации: Правильное использование SFSB с сервлетами

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

3 голосов
/ 11 мая 2010

ServletContext представляет область применения. Атрибуты области приложения являются общими для всех запросов во всех сеансах. Это «глобальные области применения». Вы не хотите хранить специфичную для клиента информацию (таким образом, сеансовую). Если в систему входит новый клиент, существующий EJB-компонент в области приложения будет переопределен для конкретного клиента и отражен для всех клиентов.

Область сеанса как раз для этой цели. Используйте это.

2 голосов
/ 11 января 2012

Просто для ясности: ServletContext инициализируется при создании сервлета (см. Спецификации сервлета) и уникален для этого самого экземпляра. Сервлет использует несколько потоков для обработки одновременных клиентских запросов. Контейнер сервлетов решает, когда создавать или уничтожать сервлеты, и делегирует клиентские запросы.

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

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