在这种情况下,我有两个会话范围的bean。一种用于登录功能。因此,此bean会记住当前用户是什么,它是在用户成功登录后设置的。
还有另一个会话范围的bean,它允许用户配置一些东西,这些东西也应该在会话中保留。用户可以随时返回配置站点,并查看他的旧数据(来自同一会话)。重要的是要知道该用户无需登录即可使用此站点。想象一下,就像网上商店中的购物车一样,在许多商店中,您甚至可以在登录之前将商品放入购物车中,并且该商品将在整个会话过程中保持不变。 这就是棘手的地方:在此配置站点上,用户可以访问某些特殊功能,例如永久保存其配置文件,但前提是必须先登录。否则,他将根本没有选择权。同样,与网上商店非常相似,如果您实际上要订购会话购物车,通常必须在该时间登录。
问题在于,如果用户首先进入配置站点,那么将首先创建该会话bean。会话Bean通过绑定注释(CurrentUser)来检索用户,该绑定注释由Login-Bean通过它的当前用户的getter由@提供。 但是,在配置站点Bean创建时,没有当前用户。 现在,如果用户随后决定去登录,则配置站点Bean仍会认为没有currentUser,因为该字段是在初始化Bean时初始化的,并且没有逻辑可以更新它。
如何处理这种情况?我是否必须开始手动从会话对象中放置和检索内容?到目前为止,仅由于@SessionScoped批注,所有事情都由JSF / Application Server自动处理。
编辑:以下代码进一步说明了这种情况:
Login-Bean:
@SessionScoped
@Named
public class LoginUserManager implements Serializable {
private UserBean currentUser;
// Logic that does the login and set the currentUser if successfull
// ...
// "Produces" currentUsers for other beans, that want to inject it simply
// via the @CurrentUser annotation, see below
@Produces
@CurrentUser
public UserBean getCurrentUser() {
return currentUser;
}
}
然后是配置管理器
@SessionScoped
@Named
public class ConfigurationManager implements Serializable {
// Session based configuration data here
// And, the current user (if any)
@CurrentUser
private UserBean currentUser;
}
如果我理解正确的话,CurrentUser注释应该是一个简单的“绑定注释”。老实说,它取自我在互联网上看到的一个片段。我发现它很优雅,认为它读起来很流畅,并且功能上与直接注入LoginUserManager然后再调用它的getCurrentUser()getter相同。
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD})
@BindingType
public @interface CurrentUser {
}