2

你好

我有 2 个托管 bean,一个 View 范围内,另一个 Session 范围内。View 作用域 bean 定义为

@ManagedBean
@ViewScoped
public class InvoiceController implements Serializable {
  private static final long serialVersionUID = 1L;

  @ManagedProperty(value="#{invoiceService}")
  private InvoiceService invoiceService;

会话范围的 bean 为

@ManagedBean
@SessionScoped
public class InvoiceService implements Serializable{

我正在使用会话范围的 bean 来保存一个用于决定是否应该呈现面板的标志,当我通过调试运行它时,我发现每次调用 sesison bean 上的方法时,它都是 bean 的一个新实例因此在请求之间不保留我的标志的值。

我究竟做错了什么?

4

2 回答 2

9

如果您是从包中导入@SessionScopedjavax.enterprise.context不是从包中导入,则可能会发生这种情况javax.faces.bean。前者仅适用于 CDI @Namedbean,而后者@ManagedBean仅适用于 JSF bean。

@ManagedBean没有任何有效范围的 JSF将默认为@NoneScoped这意味着它是在每个引用 bean 的单个 EL 表达式上新建的,例如@ManagedProperty. 这解释了您所看到的症状。

于 2012-08-09T16:59:40.327 回答
0

我有一个类似的问题。我在视图范围 bean 中使用了一个保存方法,它调用会话范围 bean 中的一个方法来更新一些值。

这是我通过调试发现的(请原谅我的非 Java 大师英语):

首次加载页面时,注入的会话 bean 的实例编号例如为 111111。但是在保存方法(以及由命令按钮或操作侦听器等操作调用的所有其他方法)中,会话 bean 突然是另一个实例(比如 222222)。

两个实例 111111 和 222222 包含完全相同的值。我现在调用的所有方法都是在 222222 实例中完成的,并且它在其中更改了我想要的值。但是 111111 实例保持不变。

所以 222222 基本上是 111111 的深层(?)克隆,甚至不是副本。

但是,在保存方法完成并重新加载页面后,原始 111111 实例再次在视图范围 bean 中使用。222222 实例刚刚被扔进了垃圾箱。

我对这个问题的解决方案:

我不再使用 ManagedProperty 注入。

相反,我编写了一些帮助代码来在需要的地方获取会话 bean(也就是在视图范围的 bean 方法中):

public Object getSessionBean(String sessionBeanName)
    {
        return FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(FacesContext.getCurrentInstance().getELContext(), null, sessionBeanName);
    }

对于上面的示例,调用将是:

InvoiceService invoiceService = (InvoiceService) helper.getSessionBean("invoiceService");

在您的方法中调用它,不要将其作为字段存储在视图范围的 bean 中。

我希望这能以某种方式帮助您解决问题。

于 2013-03-05T15:30:50.993 回答