我在这里查看了其他一些线程,我想我对如何使用 SessionScoped bean 来维护用户的登录状态有了大致的了解。但是,由于我对 JSF 2 比较陌生,因此我试图找出在登录期间和后续页面上使用 bean 来呈现页眉/页脚的最佳方式(使用相同的页面模板,但不同的菜单/链接取决于登录状态和非登录状态)。
我有一个典型的 JSF2 登录表单,它调用支持 bean(请求范围) login() 方法。所有这些都有效,我将尽快将其与容器安全性联系起来,因为我有更多的时间来处理并弄清楚这部分(领域、角色等)。
在旧的 JSF (jsp/struts) 之前的日子里,在登录时,我会添加一个对象,通常是一个用户 ID Long 值,它很容易在会话集群中复制并从中恢复完整的用户对象。这使 httpsession 数据保持最小(每个用户一个 Long 值),并且无论用户被路由到哪个服务器,我都可以确定他们已登录并提取他们的用户对象并从那里开始。
使用 JSF,我不确定执行此操作的正确方法。我有一个带有 Long userid 属性的 SessionScoped bean。在 login() 方法成功后,我使用 ExternalContext 添加 SessionScoped 对象的属性,例如:
User user = loginBean.login(username, password);
Session session = new Session();
session.setUserid(user.getId());
externalContext.getSessionMap().put("usersession", session);
externalContext.redirect(originalURL);
Session 是 SessionScoped bean,它的 CDI 名称是 usersession。我希望这是将 bean 粘贴到 HttpSession 中的正确方法,以便它可以在 EL 页面等上使用。
我不确定的第一件事是因为bean是SessionScoped,我是否需要在上面的代码中创建它之后将它放入会话中?还是因为它的范围是会话,所以它是在为我创建时自动完成的?
第二个问题是.. 我很挑剔,在用户登录之前,我不希望会话中有一个 Session 对象,即使用户 ID 为空。所以在 xhtml 页面上,如果我有类似的东西:
<h:panelGroup render="#{usersession.loggedin}"...>
这会创建会话 bean 并将其放入会话中使用它的第一个页面吗?或者在我使用上面的代码这样做之前,不会将该 Session 对象放入 HttpSession 中?我的猜测是,如果它在创建时被放入会话中,那么在任何页面上使用它都会创建它并将其粘贴在会话中。我对此不太担心..只有 Long 属性的对象在系统上每个用户的内存使用量很少,但就像我说的,我很挑剔,更想了解何时将 SessionScoped 对象存储到会议。
谢谢。