ViewScope的构造函数调用两次,不知道为什么

问题描述:

我已经看到关于调用bean构造函数和ViewScope的其他问题,我仍然有困难。我看到的问题涉及到我的应用程序中的两个特定页面。第一个是dataTable(现在它充满了随机生成的数据,但最终会调用数据库),第二个页面是一个相当简单的显示页面,其中来自所选行的信息以表单的形式显示,供编辑或查看 - 这是我的detail.xhtml页面。这是这个页面的问题;它的构造函数被调用两次:第一次当我导航到页面时,再次按下commandButton是否提交更改或取消更改无关紧要时,detail.xhtml辅助bean的构造函数被第二次调用。ViewScope的构造函数调用两次,不知道为什么

我的豆子是@ViewScoped,导入javax.faces.bean.ViewScoped。其他一些细节可能会有所作为,但如果他们这样做,我不明白为什么:我的UserDetailBean.java继承自一个基本bean(我最初调用UIBaseBean.java)。现在,我的UIBaseBean是@RequestScoped。据我所知,这不应该有所作为,因为我的UserDetailBean是@ViewScoped,请纠正我,如果我错了。

可能有所作为的其他细节是在UIBaseBean和UserDetailBean的构造函数中设置一个变量。我想在我的页面顶部的工具栏中显示用户的位置。为此,我在UIBaseBean中创建了一个变量:

protected String toolbarDescription; 

我还在UIBaseBean中提供了setter和getter。在UIBaseBean的构造函数我定义变量:

toolbarDescription = "fix me"; 

这个定义只是让我知道要覆盖在支持Bean的变量在我的应用程序的任何特定页面。在我的UserDetailBean中,我为字符串toolbarDescription分配一个新值。该值显示在detail.xhtml页面上。否则,我的detail.xhtml页面的bean非常流行,它会获取并设置detail.xhtml页面上表单中数据的显示属性。

设置详细信息页面,以便重定向发生导航,导航(按下commandButton时)导航发生重定向。我尝试过使用faces-config导航规则,有和没有重定向,隐式导航有和没有重定向,但UserDetailBean构造函数总是被调用两次。

哦,我在我的UserDetailBean构造函数的toolbarDescription变量上设置了一个断点,该程序停止了两次程序:首次调用页面时,以及在详细信息页面上按下commandButton之后再次停止该程序。

从我所描述的,谁能告诉我为什么我的构造函数被调用两次?我是否错误地设计了我的bean,还是我的应用程序中的问题更深?

import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 
import javax.faces.event.ActionEvent; 
import [package name].UIBaseBean;  
import java.util.Locale; 
import javax.faces.bean.ManagedProperty; 


@ManagedBean 
@ViewScoped 

public class UserDetailBean extends UIBaseBean { 

@ManagedProperty(value = "#{param.action}") 
private String action; 

private String firstName; 
private String lastName; 
private String jobTitle; 
private String DOH; 
private String location; 
private String status; 
private String comments; 
@ManagedProperty(value = "#{param.id}") 
private String id; 
private String tabTitle; 

private boolean editMode; 
private boolean viewMode; 

private ClUserDetail dBUserDetail;  

    /** Creates a new instance of UserDetailBean */ 
    public UserDetailBean() { 
     toolbarDescription = CoreMsgBundle.getMessageFromResourceBundle("UserDetail", Locale.ENGLISH); 
    } 

您需要从UIBaseBean删除@RequestScoped和其他相关注释(并使其abstract)。

一旦做到这一点,还需要通过<f:viewParam>固定在#{param}@ManagedProperty被定义或要由ExternalContext#getRequestParameterMap(),而不是获得。将具有较短范围的东西注入具有较大范围的东西是不可能的(因为在接受者范围内可能存在更多东西,因此不清楚应该注入哪一个)。 JSF会在bean的构建过程中抛出一个例外。

+0

非常感谢你,这正如我希望原始代码能够工作一样。至于@ManagedProperty - 这是一个没有很好理解的小信息的例子,是一件坏事。我读[这个答案](http://*.com/questions/4888942/viewparam-vs-managedpropertyvalue-param-id),并认为,“哦,这是一个好主意,我会在我的应用程序中做到这一点”。 – Sean 2011-02-04 18:34:53