ViewScope构造函数调用了两次,不确定原因

我已经看到了关于调用bean构造函数和ViewScope的其他问题,我仍然遇到了困难。 我看到的问题涉及我的应用程序中的两个特定页面。 第一个是dataTable(现在它填充了随机生成的数据,但最终将调用数据库),第二个页面是一个相当简单的显示页面,其中所选行的信息以表格forms显示,用于编辑或查看 – 这是我的detail.xhtml页面。 这个页面的bean就是问题; 它的构造函数被调用两次:首先当我导航到页面时,再次当我按下commandButton是否提交更改或取消更改无关紧要时,detail.xhtml支持bean的构造函数被第二次调用。

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

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

 protected String toolbarDescription; 

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

 toolbarDescription = "fix me"; 

这个定义就是这样我知道在我的应用程序中覆盖任何特定页面的支持bean中的变量。 在我的UserDetailBean中,我为String 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 )。

完成后,您还需要修复#{param}上的@ManagedProperty ,或者由定义,或者通过ExternalContext#getRequestParameterMap()来获取。 这是不可能将具有较短范围的东西注入具有较大范围的东西(因为不清楚应该注入哪一个,因为在接受者的范围内可以有更多的注入)。 在bean构建期间,JSF会抛出exception。