2011-12-16 2 views
4

У меня есть EJB с состоянием, который я использую для хранения текущей информации пользователя в моем приложении. Этот EJB вводится в контроллер сервлетов и используется для хранения последнего зарегистрированного пользователя. Однако сеанс, похоже, одинаковый для каждого отдельного клиента.Stateful EJB и тот же сеанс реплицируется по клиентам

Пример кода EJB:

Stateful 
@LocalBean 
public class CurrentUserBean { 

private string Username; 

public void setUser(String un) 
{ 
    Username = un; 
} 

.... 

Пример Servlet Код:

public class MainController extends HttpServlet { 
     @EJB private CurrentUserBean userBean; 

     protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

       HttpSession session = request.getSession(); 
       String name = session.getAttribute("username"); 

       userBean.setUser(name); 
       ...... 

Теперь, когда приложение развернуто на моем сервере, и у меня есть много разных людей, говорящих на сервер от нескольких клиентов , имя пользователя всегда задается последним пользователем, который вошел в систему. Другими словами, кажется, что сеансовый компонент с сохранением состояния сохраняет одно и то же состояние для всех клиентов. Это смутило меня сильно, как я прочитал в учебнике Й Java 6 следующей цитату со страницы 247:

В сессионном компоненте, переменные экземпляра представляют состояние уникального сеанс клиента/боба. Поскольку клиент взаимодействует с его компонентом («переговоры»), это состояние часто называют диалоговым состоянием . Как следует из его названия, сеансовый компонент похож на интерактивный сеанс . Компонент сеанса не используется; он может иметь только один одного клиента, так же, как интерактивный сеанс может иметь только одного пользователя. Когда клиент завершает работу, его сеансовый компонент представляется , и он больше не связан с клиентом.

Может кто-нибудь объяснить, почему это происходит, а также объяснить, как использовать фасоль с естественным состоянием надлежащим образом, чтобы не сохранять одно и то же состояние по всем клиентам?

спасибо.

+0

Вы получаете различные сеансы HTTP или же слишком? – Thomas

+0

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

ответ

6

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

Вам не следует вводить компонент, но извлекать его из контекста в методе processRequest.

InitialContext ctx= new InitialContext(); 
CurrentUserBean userBean = (CurrentUserBean)ctx.lookup("CurrentUserBean"); 
+2

+1. Создается только один экземпляр сервлета, и все запросы обрабатываются одним и тем же экземпляром в разных потоках. Таким образом, в основном тот же экземпляр EJB разделяется всеми клиентами. –

1

Или вы используете

@Inject 
Instance<CurrentUserBean> currentUserBeanInstance; 

protected void processRequest(... 
    CurrentUserBean currentUserBean = currentUserBeanInstance.get(); 

только Java EE 6

+0

Вам также нужен CDI. –