5

我有一个有状态的 EJB,用于将当前用户信息保存在我的应用程序中。这个 EJB 被注入到 servlet 控制器并用于存储最后登录的用户。但是,会话似乎在每个客户端上都是相同的。

示例 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);
                ......

现在,当应用程序部署在我的服务器上并且我有许多不同的人从几个不同的客户端与服务器交谈时,用户名总是设置为最后一个登录的用户。换句话说,看起来好像有状态会话 bean在所有客户端上保持相同的状态。这让我非常困惑,因为我在 java 6 ee 教程中读到了第 247 页的以下引用:

在有状态会话 bean 中,实例变量表示唯一客户端/bean 会话的状态。因为客户端与其 bean 交互(“交谈”),所以这种状态通常称为会话状态。顾名思义,会话 bean 类似于交互式会话。会话 bean 不共享;它只能有一个客户端,就像交互式会话只能有一个用户一样。当客户端终止时,它的会话 bean 似乎也终止并且不再与客户端关联。

有人可以解释为什么会发生这种情况,还可以解释如何以正确的方式使用有状态的 bean,而不是在所有客户端上保持相同的状态?

谢谢你。

4

2 回答 2

6

尽管有状态会话 bean 具有每个用户的状态(实际上是会话),但 servlet 没有。通过像现在这样注入它,这个 servlet 使用了一个 bean,因为它是在创建 servlet 时注入的(可能是属于第一个访问者的 bean)。

您不应该注入 bean,而是从processRequest方法内的上下文中检索它。

InitialContext ctx= new InitialContext();
CurrentUserBean userBean = (CurrentUserBean)ctx.lookup("CurrentUserBean");
于 2011-12-16T16:12:05.963 回答
2

或者你使用

@Inject
Instance<CurrentUserBean> currentUserBeanInstance;

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

仅 Java EE 6

于 2013-06-12T13:57:45.907 回答