使用有状态会话Bean来跟踪用户的会话

时间:2011-12-12 19:58:32

标签: session ejb javabeans httpsession stateful

这是我的第一个问题,我希望我做得对。

我需要在Java EE项目上工作,因此,在开始之前,我正在尝试做一些简单的事情,看看我能不能做到。

我坚持使用有状态会话豆

以下是问题: 如何使用 SFSB 跟踪用户的会话? 我看到的所有示例最终都将 SFSB “放入” HttpSession 属性。 但我不明白为什么! 我的意思是,如果bean是STATEFUL,为什么我必须使用 HttpSession 来保存它?

EJB容器的任务不是将正确的 SFSB 返回给客户端吗?

我尝试过一个简单的计数器豆。 在不使用会话的情况下,两个不同的浏览器具有相同的计数器bean(单击“增量”会更改它们的值)。 使用session,我有两个不同的值,每个值对应每个浏览器(点击Firefox上的“increment”,只添加一个到Firefox的bean)。

但是我的老师告诉 SFSB 保持“与客户端的会话状态”,那么为什么它不能在不使用 HttpSession 的情况下工作?

如果我理解正确,不是将 HttpSession SFSB 一起使用,而不是使用 SLSB 吗?

我希望我的问题很明确,而且我的英语不是那么差!

编辑: 我正在研究登录系统。 一切顺利,完成登录后,我会看到一个显示用户数据的个人资料页面。 但重新加载页面会使我的数据消失! 我已经尝试在记录时添加 HttpSession ,但这样做会使数据在注销后保持不变!

2 个答案:

答案 0 :(得分:27)

有状态会话Bean(SFSB)必须与Web环境中的HTTP会话相结合,因为它是一个纯粹的业务bean,它本身对Web层一无所知。

传统上,EJB甚至必须存在于自己的模块(EJB模块)中,如果他们愿意,甚至无法访问Web工件。这是分层系统的一个方面。有关详细信息,请参阅Packaging EJB in JavaEE 6 WAR vs EAR

有状态会话Bean的原始客户端是Swing桌面应用程序,它们通过二进制协议与远程EJB服务器通信。 Swing应用程序将通过代理/存根对象获取与远程有状态会话Bean的连接。嵌入在此代理中的是服务器可以与特定SFSB关联的某种ID。通过保持这个代理对象,Swing客户端可以重复调用它,那些将转到同一个bean实例。这将在客户端和服务器之间创建一个会话。

对于Web应用程序,当浏览器向Java EE Web应用程序发出初始请求时,它会获得服务器可以与特定JSESSIONID实例关联的HTTPSession。通过保持此JSESSIONID,浏览器可以为其提供每个后续请求,这将激活相同的http会话服务器端。

因此,这些概念非常相似,但它们不会自动相互映射。

浏览器只获取JSESSIONID并且不知道任何SFSB ID。与Swing应用程序不同,浏览器与网页进行通信,而不是直接与Java bean进行通信。

为了将客户端的请求映射到特定的有状态会话bean,EJB容器只关心通过SFSB代理提供的ID。它无法查看调用是否源自Web模块中的代码,并且不能/不应该真正访问任何HTTP上下文。

作为访问SFSB的客户端代码的Web层必须“保持”特定的代理引用。坚持Web层中的某些内容通常意味着将其存储在HTTP会话中。

然而,有一种名为CDI的桥接技术可以实现这种自动连接。如果使用CDI @SessionScoped注释SFSB并通过CDI获取对SFSB的引用(例如使用@Inject),则不必手动将SFSB放入http会话。然而,幕后CDI无论如何都会做到这一点。

答案 1 :(得分:3)

您需要使用@SessionScoped而不是@RequestScoped来定义bean(如果您正在寻找HttpSession等效解决方案)

类似

@SessionScoped
public class SessionInfo implements Serializable{
   private String name;
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
}

看看下面的内容(详细解释)

http://www.oracle.com/technetwork/articles/java/cdi-javaee-bien-225152.html