Java:跟踪用户登录会话 - 会话 EJB 与 HTTPSession

2022-09-04 20:46:52

如果我想使用我的Web应用程序跟踪每个客户端的对话状态,那么使用哪个更好的选择 - 会话Bean或HTTP会话 ?

使用 HTTP 会话:

//request is a variable of the class javax.servlet.http.HttpServletRequest
//UserState is a POJO
HttpSession session = request.getSession(true);
UserState state = (UserState)(session.getAttribute("UserState"));
if (state == null) { //create default value .. }
String uid = state.getUID();
//now do things with the user id

使用会话 EJB:

在 ServletContextListener 的实现中,在 中注册为 Web 应用程序侦听器:WEB-INF/web.xml

//UserState NOT a POJO this this time, it is
//the interface of the UserStateBean Stateful Session EJB
@EJB
private UserState userStateBean;

public void contextInitialized(ServletContextEvent sce) {
    ServletContext servletContext = sce.getServletContext();
    servletContext.setAttribute("UserState", userStateBean);
    ...

在 JSP 中:

public void jspInit() {
    UserState state = (UserState)(getServletContext().getAttribute("UserState"));
    ...
}

在同一 JSP 正文的其他地方:

String uid = state.getUID();
//now do things with the user id

在我看来,它们几乎是相同的,主要区别在于UserState实例在前者中传输,而在后者的情况下则被传输。HttpRequest.HttpSessionServletContext

这两种方法中哪一种更健壮,为什么?


答案 1

正如@BalusC所指出的,在你的例子中,EJB 对所有客户端都是一样的,而不是你想要的。

您仍然可以更改它,并且每个客户端有一个 EJB,例如,如果您在用户登录时创建 EJB 并将其存储在会话中,或者类似的东西。

但是,使用 有状态会话 Bean (SFSB) 和有状态会话 Bean (SFSB) 之间还有其他更细微的区别。尤其是这两个:HttpSession

  1. 异常处理。如果某个事务在 EJB 中失败,那么该 Bean 将失效,并且不能再使用。这可能会使 Web 应用程序中的错误处理策略复杂化。
  2. 并发性。无法同时访问同一 SFSB,因此您需要在 Web 图层中对其进行同步。同样,这可能会使设计复杂化。

有关更多详细信息,请参阅此答案:在 Servlet 中正确使用 SFSB

总而言之:我建议在你的案件中采取这种方法并反对SFSB;仅当 SFSB 提供了您无法使用的内容时,才使用 SFSB,但事实并非如此。HttpSessionHttpSession


答案 2

表示应用程序范围。应用程序范围的属性在所有会话中的所有请求之间共享。它是“应用范围的全局变量”。您不希望将客户端(因此,会话)特定信息存储在那里。如果新的客户机登录,那么应用程序作用域中的现有 EJB 将被特定于客户机的 EJB 覆盖,并反映给所有客户机。ServletContext

会话范围正是用于此目的。利用它。


推荐