【问题标题】:Using a Stateful Session Bean to track an user's session使用有状态会话 Bean 跟踪用户的会话
【发布时间】:2012-01-18 18:54:57
【问题描述】:

这是我在这里的第一个问题,我希望我做对了。

我需要处理一个 Java EE 项目,所以在开始之前,我会尝试做一些简单的事情,看看我是否可以做到。

我被Stateful Session Beans困住了。

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

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

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

但我的老师告诉我,SFSB 保持“与客户端的对话状态”,那么为什么不使用 HttpSession 就不能正常工作呢?

如果我理解正确,使用 HttpSessionSFSB 是否与使用 SLSB 相同?

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

编辑: 我正在开发一个登录系统。 一切都很好,完成登录后,它会将我带到显示用户数据的个人资料页面。 但是重新加载页面会使我的数据消失! 我曾尝试在记录时添加 HttpSession,但这样做会使数据在注销后仍然存在!

【问题讨论】:

    标签: session ejb javabeans httpsession stateful


    【解决方案1】:

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

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

    Stateful Session Beans 的原始客户端是 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 在幕后都会这样做。

    【讨论】:

    • 很好的答案,阿扬。但是,我相信您在答案的最后一段是指@SessionScoped
    【解决方案2】:

    您需要使用@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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-02
      • 1970-01-01
      • 2015-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-26
      相关资源
      最近更新 更多