使用 Stateful Session Bean 跟踪用户会话
这是我的第一个问题,我希望我做得对。
我需要从事 Java EE 项目,因此,在开始之前,我尝试做一些简单的事情,看看是否能做到。
我陷入了有状态会话 Bean 的困境。
这是问题: 如何使用SFSB来跟踪用户的会话? 我看到的所有示例最终都将 SFSB“放入”HttpSession 属性中。 但我不明白为什么! 我的意思是,如果 bean 是 STATEFUL,为什么我必须使用 HttpSession 来保留它?
EJB 容器的任务不是将正确的 SFSB 返回给客户端吗?
我尝试过使用简单的反豆。 在不使用会话的情况下,两个不同的浏览器具有相同的计数器 bean(单击“增量”更改了它们的值)。 使用会话,我有两个不同的值,每个值适用于每个浏览器(在 Firefox 上单击“增量”,仅向 Firefox 的 bean 添加一个值)。
但我的老师告诉我,SFSB 保持“与客户端的对话状态”,那么为什么它不能在不使用 HttpSession 的情况下工作呢?
如果我理解正确的话,使用 HttpSession 和 SFSB 与使用 SLSB 不是一样吗?
我希望我的问题很清楚并且我的英语没那么差!
编辑 : 我正在开发登录系统。 一切都很顺利,完成登录后,我会进入显示用户数据的个人资料页面。 但是重新加载页面会使我的数据消失! 我尝试在记录时添加HttpSession,但这样做会使数据即使在注销后仍然保留!
it's my first question here and I hope that I'm doing it right.
I need to work on a Java EE project, so, before starting, I'm trying to do something simple and see if I can do that.
I'm stuck with Stateful Session Beans.
Here's the question :
How can I use a SFSB to track an user's session?
All the examples that I saw, ended up in "putting" the SFSB into a HttpSession attribute.
But I don't understand why!
I mean, if the bean is STATEFUL, why do I have to use the HttpSession to keep it?
Isn't an EJB Container's task to return the right SFSB to the client?
I've tried with a simple counter bean.
Without using the session, two different browsers have the same counter bean (clicking on "increment" changed the value for both of them).
Using session, I have two different values, each for every browser (clicking on "increment" on Firefox, added one just to Firefox's bean).
But my teacher told that a SFSB keeps the "conversational state with a client", so why it doesn't just work without using a HttpSession ?
If I understood correctly , isn't using HttpSession with a SFSB the same of doing it with a SLSB instead?
I hope that my question(s) is clear and that my English is not that poor!
EDIT :
I'm working on a login system.
Everything goes fine and after completing the login it takes me to a profile page that show user's data.
But reloading the page makes my data disappear!
I've tried adding HttpSession while logging but doing in this way makes the data stay even after the logout!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有状态会话 Bean (SFSB) 必须与 Web 环境中的 HTTP 会话结合起来,因为它是一个纯业务 Bean,本身对 Web 层一无所知。
传统上,EJB 甚至强制存在于它们自己的模块(EJB 模块)内,如果它们愿意,甚至无法访问 Web 工件。这是分层系统的一个方面。请参阅在 JavaEE 6 WAR 与 EAR 中打包 EJB 了解更多相关信息。
有状态会话 Bean 的原始客户端包括 Swing 桌面应用程序,它们通过二进制协议与远程 EJB 服务器进行通信。 Swing 应用程序将通过代理/存根对象获得与远程有状态会话 Bean 的连接。该代理中嵌入了某种 ID,服务器可以将其与特定 SFSB 关联。通过保留此代理对象,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 在幕后都会这样做。A Stateful Session Bean (SFSB) has to be combined with the HTTP session in a web environment, since it's a pure business bean that itself knows nothing about the web layer.
Traditionally EJBs even mandatory lived inside their own module (the EJB module), that couldn't even access web artifacts if they wanted to. This is an aspect of layered systems. See Packaging EJB in JavaEE 6 WAR vs EAR for more information about that.
The original clients for Stateful Session Beans were among others Swing desktop applications, that communicated with the remote EJB server via a binary protocol. A Swing application would obtain a connection to a remote Stateful Session Bean via a proxy/stub object. Embedded in this proxy is an ID of some kind that the server can associate with a specific SFSB. By holding on to this proxy object, the Swing client can make repeated calls to it and those will go to the same bean instance. This will thus create a session between the client and the server.
In the case of a web application, when a browser makes an initial request to a Java EE web application it gets a
JSESSIONID
that the server can associate with a specificHTTPSession
instance. By holding on to thisJSESSIONID
, the browser can provide it with each followup request and this will activate the same http session server-side.So, those concepts are very similar, but they do not automatically map to each other.
The browser only gets the
JSESSIONID
and has no knowledge about any SFSB ID. Unlike the Swing application, the browser communicates with web pages, not directly with Java beans.For mapping the client's request to a specific stateful session bean, the EJB container only cares about the ID provided via the SFSB proxy. It can't see if the call happened to originate from code in the web module and can't/shouldn't really access any HTTP contexts.
The web layer being the client code that accesses the SFSB must 'hold on' to a specific proxy reference. Holding on to something in the web layer typically means storing it in the HTTP session.
There is however a bridge technology called
CDI
that can make this automatic connection. If you annotate your SFSB with CDI's@SessionScoped
and obtain a reference to the SFSB via CDI (e.g. using@Inject
), you don't have to manually put your SFSB into the http session. However, behind the scenes CDI will do exactly that anyway.您需要使用 @SessionScoped 而不是 @RequestScoped 定义 bean(如果您正在寻找 HttpSession 等效解决方案),
内容
请查看以下
(详细说明) http://www.oracle.com/technetwork/articles/java/cdi-javaee-bien-225152.html
You need to define the bean with @SessionScoped instead of @RequestScoped (if you are looking for HttpSession equivalent solution)
something like
Have a look at following (explained in detail)
http://www.oracle.com/technetwork/articles/java/cdi-javaee-bien-225152.html