2011-12-12 128 views
15

这是我的第一个问题,我希望我做对了。使用有状态会话Bean来跟踪用户的会话

我需要在Java EE项目上工作,所以,在开始之前,我试图做一些简单的事情,看看我能否做到这一点。

我被困在有状会话豆

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

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

我试过了一个简单的计数器bean。 不使用会话,两个不同的浏览器具有相同的计数器bean(单击“增量”更改了它们的值)。 使用会话,我有两个不同的值,每个对于每个浏览器(点击Firefox上的“增量”,仅添加一个到Firefox的bean)。

但我的老师告诉记者,一个SFSB保持“会话状态与客户端”,那么为什么它不只是不使用HttpSession中工作

如果我理解正确,没有使用HttpSession中SFSB同一个SLSB而不是做呢?

我希望我的问题很清楚,我的英语不是那么差!

编辑: 我正在登录系统上工作。 一切都很顺利,完成登录后,它会将我带到显示用户数据的配置文件页面。 但重新加载页面会使我的数据消失! 我已经尝试在登录时添加HttpSession,但以这种方式进行操作会使数据在注销后仍然保留!

回答

25

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

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

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

对于Web应用程序,当浏览器向Java EE Web应用程序发出初始请求时,它将获得服务器可以与特定的HTTPSession实例关联的JSESSIONID。通过坚持这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无论如何都会这样做。

+0

伟大的答案,阿尔詹。不过,我相信你的意思是@SessionScoped在你的回答的最后一段 –

+0

@ Joe.M感谢你发现错误;)修正! –

3

您需要定义与@SessionScoped代替@RequestScoped豆(如果你正在寻找的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