在多个@ManagedBeans 的代码中重用对象及其方法
Reuse object and its methods in code of multiple @ManagedBeans
我只想通过我的 @RequestScoped
LoginBean 设置我的用户对象一次。然后我想通过 CDI 在其他 @ManagedBean 中重用它的 setter、getter 和 isLoggedIn()
方法。
设置用户对象的请求范围Class
@ManagedBean
@RequestScoped
public class LoginBean {
@ManagedProperty(value = "#{bean}")
protected Bean bean;
private String username;
private String password;
public String login() {
bean.setLoggedInUser(userDao.getUser(username));
return "index";
}
// Getters and Setters, including for the @ManagedProperty baseBean.
}
SessionScoped Class 存储用户对象
@ManagedBean
@SessionScoped
public class Bean {
private User loggedInUser = null;
public boolean isLoggedIn() {
return loggedInUser != null;
}
// Getters and setters for loggedInUser
}
Class 我想引用 loggedInuser 的地方
@ManagedBean
@RequestScoped
public class ShowUserDetails extends Bean {
private Details details = new Details();
public void showDetails() {
if(isLoggedIn()) { // THIS ALWAYS RETURNS FALSE
// Do stuff
}
}
}
到目前为止的解决方案
- 我可以在每个需要 loggedInUser 的 Backing Bean 中列出一个 Bean
@ManagedProperty
。这似乎是错误的,因为我在每个 class. 中复制粘贴了两行
- 我可以使用
context.getApplication().evaluateExpressionGet()
从 FacesContext 获取 Bean class 的实例。这允许我有一种方法来检索 superclass 中的 Bean 实例,但这似乎也是错误的。也就是说,如果我找不到纯 CDI 解决方案,这就是我将采用的方法。
您担心在每个 bean 中添加一次两行代码,但您确实想编写
if(isLoggedIn()) { // THIS ALWAYS RETURNS FALSE
// Do stuff
}
并且很可能在一个 bean 中多次出现(并且很可能也在 else 语句中)。
然后我肯定会使用注释和拦截器
另请参阅
我的解决方案是使用 HttpSession 来存储 User 对象,而不是使用 class 成员变量。这让我有一个 class 处理 getting/setting 而所有其他 classes 可以简单地调用 'getLoggedinUser' 来检索整个对象而无需访问数据库。
private HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
private static final String LOGGED_IN_USER = "loggedInUser";
public User getLoggedInUser() {
return (User) session.getAttribute(LOGGED_IN_USER);
}
public void setLoggedInUser(User user) {
session.setAttribute(LOGGED_IN_USER, user);
}`
我只想通过我的 @RequestScoped
LoginBean 设置我的用户对象一次。然后我想通过 CDI 在其他 @ManagedBean 中重用它的 setter、getter 和 isLoggedIn()
方法。
设置用户对象的请求范围Class
@ManagedBean
@RequestScoped
public class LoginBean {
@ManagedProperty(value = "#{bean}")
protected Bean bean;
private String username;
private String password;
public String login() {
bean.setLoggedInUser(userDao.getUser(username));
return "index";
}
// Getters and Setters, including for the @ManagedProperty baseBean.
}
SessionScoped Class 存储用户对象
@ManagedBean
@SessionScoped
public class Bean {
private User loggedInUser = null;
public boolean isLoggedIn() {
return loggedInUser != null;
}
// Getters and setters for loggedInUser
}
Class 我想引用 loggedInuser 的地方
@ManagedBean
@RequestScoped
public class ShowUserDetails extends Bean {
private Details details = new Details();
public void showDetails() {
if(isLoggedIn()) { // THIS ALWAYS RETURNS FALSE
// Do stuff
}
}
}
到目前为止的解决方案
- 我可以在每个需要 loggedInUser 的 Backing Bean 中列出一个 Bean
@ManagedProperty
。这似乎是错误的,因为我在每个 class. 中复制粘贴了两行
- 我可以使用
context.getApplication().evaluateExpressionGet()
从 FacesContext 获取 Bean class 的实例。这允许我有一种方法来检索 superclass 中的 Bean 实例,但这似乎也是错误的。也就是说,如果我找不到纯 CDI 解决方案,这就是我将采用的方法。
您担心在每个 bean 中添加一次两行代码,但您确实想编写
if(isLoggedIn()) { // THIS ALWAYS RETURNS FALSE
// Do stuff
}
并且很可能在一个 bean 中多次出现(并且很可能也在 else 语句中)。
然后我肯定会使用注释和拦截器
另请参阅
我的解决方案是使用 HttpSession 来存储 User 对象,而不是使用 class 成员变量。这让我有一个 class 处理 getting/setting 而所有其他 classes 可以简单地调用 'getLoggedinUser' 来检索整个对象而无需访问数据库。
private HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
private static final String LOGGED_IN_USER = "loggedInUser";
public User getLoggedInUser() {
return (User) session.getAttribute(LOGGED_IN_USER);
}
public void setLoggedInUser(User user) {
session.setAttribute(LOGGED_IN_USER, user);
}`