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