5

我正在使用带有购物车样式流程的 JSF 开发一个 Java EE Web 应用程序,因此我想收集多个页面上的用户输入,然后对其进行处理。

我正在考虑为此使用 EJB 3 有状态会话 bean,但我的研究使我相信 SFSB 不绑定到客户端的 http 会话,因此我必须通过 httpSession 手动跟踪它,一些附带问题这里 。. .

1)为什么称为会话bean,据我所知,它与会话无关,我可以通过将pojo存储在会话中来实现相同的目的。

2)能够注入它有什么意义,如果我要注入的只是这个SFSB的一个新实例,那么我还不如使用pojo?

所以回到我看到的主要问题,JSF 是一种表示技术,所以它不应该用于逻辑,但它似乎是收集用户输入的完美选择。

我可以将 JSF 会话范围 bean 设置为我的所有请求 bean 的托管属性,这意味着它被注入到它们中,但与 SFSB 不同的是,JSF 托管会话范围 bean 绑定到 http 会话,因此始终注入相同的实例只要 http 会话没有失效。

所以我有多层

第一层)处理表示的 JSF 管理的请求范围 bean,每页 1 个。
第 2 层)一个 JSF 管理的会话范围 bean,其值由请求 bean 在其中设置。
第三层)一个无状态会话 EJB,它对 JSF 会话范围 bean 中的数据执行逻辑。

为什么这么糟糕?

另一种选择是使用 SFSB,但是我必须将它注入到我的初始请求 bean 中,然后将其存储在 http 会话中并在每个后续请求 bean 中重新获取它 - 看起来很混乱。

或者我可以将所有内容都存储在会话中,但这并不理想,因为它涉及使用文字键和强制转换。等..等容易出错。. . 和凌乱!

任何想法都值得赞赏,我觉得我正在与这项技术作斗争而不是使用它。

谢谢

4

3 回答 3

9

为什么称为会话bean,据我所知,它与会话无关,我可以通过在会话中存储一个pojo来实现相同的目的。

来自旧的J2EE 1.3 教程

什么是会话 Bean?

会话 bean 代表 J2EE 服务器内的单个客户端。为了访问部署在服务器上的应用程序,客户端调用会话 bean 的方法。会话 bean 为其客户端执行工作,通过在服务器内部执行业务任务来保护客户端免受复杂性的影响。

顾名思义,会话 bean 类似于交互式会话。会话 bean 不是共享的——它可能只有一个客户端,就像交互式会话可能只有一个用户一样。与交互式会话一样,会话 bean 不是持久的。(也就是说,它的数据没有保存到数据库中。)当客户端终止时,它的会话 bean 似乎也终止了,并且不再与客户端关联。

所以它与“会话”有关。但会话不一定意味着“HTTP会话”

能够注入它有什么意义,如果我要注入的只是这个 SFSB 的一个新实例,那么我还不如使用 pojo?

好吧,首先,您不要在无状态组件中注入 SFSB(注入另一个 SFSB 就可以了),您必须进行查找。其次,在 HTTP 会话和 SFSB 之间进行选择实际上取决于您的应用程序和您的需求。从纯理论的角度来看,HTTP 会话应该用于表示逻辑状态(例如,您在多页面表单中的位置),而 SFSB 应该用于业务逻辑状态。这在 TSS 上的“旧” HttpSession 与有状态会话 bean线程中得到了很好的解释,该线程也有一个很好的例子,其中 SFSB 是有意义的:

您可能希望使用有状态会话 bean 来跟踪特定事务的状态。即有人买火车票。

Web Session 跟踪用户在 html 页面流中的状态。但是,如果用户随后通过不同的渠道(例如 wap 电话)或通过呼叫中心获得了对系统的访问权,您仍然想知道购票交易的状态。

但是 SFSB 并不简单,如果您不需要证明使用它们的合理性,我的实用建议是坚持使用 HTTP 会话(特别是如果所有这些对您来说都是新的)。以防万一,请参阅:

所以回到我看到的主要问题,JSF 是一种表示技术,所以它不应该用于逻辑,但它似乎是收集用户输入的完美选择。

那不是业务逻辑,那是表示逻辑。

所以我有多层(...)

不,您可能有一个客户层、一个表示层、一个业务层、一个数据层。你所描述的看起来更像层(甚至不确定)。看:

为什么这么糟糕?

我不知道,我不知道您在说什么 :) 但是您可能应该只是将多页表单信息收集到一个 SessionScoped bean 中,并在流程结束时调用一个无状态会话 Bean (SLSB)。

于 2010-09-02T23:57:03.070 回答
6

1)为什么称为会话bean,据我所知,它与会话无关,我可以通过将pojo存储在会话中来实现相同的目的。

更正:EJB 会话与 HTTP 会话无关。在 EJB 中,粗略地说,客户端是 servlet 容器,服务器是 EJB 容器(都运行在 Web/应用程序服务器中)。在 HTTP 中,客户端是 Web 浏览器,服务器是 Web/应用程序服务器。

现在更有意义了吗?

2)能够注入它有什么意义,如果我要注入的只是这个SFSB的一个新实例,那么我还不如使用pojo?

将 EJB 用于事务性业务任务。使用会话范围的托管 bean 来存储 HTTP 会话特定的数据。顺便说一句,两者都不是POJO。只是Javabeans。

为什么我不应该将 JSF SessionScoped bean 用于逻辑?

如果您没有从事务性业务任务和 EJB 围绕它提供的抽象中受益,那么仅在一个简单的 JSF 托管 bean 中执行它确实不是一个糟糕的选择。这也是基本 JSF 应用程序中的常规方法。然而,这些操作通常发生在请求范围的托管 bean 中,其中会话范围的托管 bean 被注入为@ManagedProperty.

但是由于您已经在使用 EJB,我会质疑是否没有使用 EJB 的特定原因。如果这是占上风的业务要求,那么我会坚持下去。至少,你的会话混乱现在应该被清除了。

于 2010-09-02T17:14:38.877 回答
2

以防万一您不知道这一点,并且作为对您的答案的一小部分贡献,您确实可以使用 @SessionScoped 注释 SFSB,CDI 将处理 EJB 的生命周期......这将绑定 EJB到 CDI 管理的 Http Session。只是让你知道,因为在你的问题中你说:

but my research leads me to believe that a SFSB is not tied to a client's http session, so I would have to manually keep track of it via an httpSession, some side questions here . . .

此外,您可以按照您的建议进行操作,但这取决于您的要求,直到 CDI bean 获得声明性事务支持或扩展的持久性上下文等,您会发现自己编写了很多样板代码,这会使您的 bean 不那么干净。当然,您也可以使用像 Seam(现在移至DeltaSpike)这样的框架,通过它们的扩展来增强 bean 的某些功能。

所以我会说是的,乍一看你可能觉得没有必要使用有状态的 EJB,但某些用例可能通过它们更好地解决。如果用户将产品添加到他的购物车中,而另一个用户稍后添加了相同的产品,但库存中只有一个单位,谁会得到它?结账速度更快的人?还是第一个添加它的人?如果您想访问您的实体管理器以在用户决定随机关闭他的浏览器的情况下持久保存卡丁车怎么办,或者如果您有生成多个页面的事务并且您希望每个步骤都同步到数据库怎么办?(不建议长时间保持交易开放,但也许在某些情况下需要这样做?)您可以使用 SLSB,但有时使用 SFSB 会更好、更清洁。

于 2012-11-17T03:35:17.537 回答