有状态EJB和跨客户端复制的同一会话

时间:2011-12-16 16:00:33

标签: java java-ee ejb stateful-session-bean

我有一个有状态的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,而不是在所有客户端中保持相同的状态吗?

谢谢。

2 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:1)

或者你使用

@Inject
Instance<CurrentUserBean> currentUserBeanInstance;

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

仅限Java EE 6