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

发布于 2024-10-16 02:09:56 字数 2324 浏览 6 评论 0原文

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

我的 bean 是 @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 中,我为 StringtoolbarDescription 分配了一个新值。该值显示在detail.xhtml 页面上。除此之外,我的detail.xhtml 页面的bean 非常简单,它获取并设置用于在detail.xhtml 页面上的表单中显示数据的属性。

详细信息页面已设置,以便通过重定向进行导航,并通过重定向进行导航离开(按下命令按钮时)。我尝试过使用带有和不带重定向的 faces-config 导航规则,以及带有和不带重定向的隐式导航,但 UserDetailBean 构造函数总是被调用两次。

哦,我在 UserDetailBean 构造函数中的工具栏描述变量上设置了一个断点,这会停止程序两次:第一次调用页面时,以及在按下详细信息页面上的命令按钮后再次停止。

根据我的描述,谁能告诉我为什么我的构造函数被调用两次?我的 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);
    }

I've seen the other questions regarding calling a bean constructor and ViewScope, and I'm still having difficulty. The problem I'm seeing involves two specific pages in my application. The first is a dataTable (for now it is filled with randomly generated data but will eventually call a database), the second page is a fairly simple display page in which information from the selected row is displayed in a form for either editing or viewing - this is my detail.xhtml page. It is the bean for this page that is the issue; its constructor is called twice: first when I navigate to the page, again when I press the commandButton whether to submit changes or cancel changes does not matter, the detail.xhtml backing bean's constructor is called a second time.

My bean is @ViewScoped, importing javax.faces.bean.ViewScoped. A few other details that might make a difference, but if they do I don't understand why: my UserDetailBean.java inherits from a base bean (which I so originally call UIBaseBean.java). Now, my UIBaseBean is @RequestScoped. As I understand, this shouldn't make a difference because my UserDetailBean is @ViewScoped, please correct me if I'm wrong.

The other detail that might make a difference is the setting of a variable in the constructor of both the UIBaseBean and the UserDetailBean. I want to display the location of the user in a toolbar at the top of my pages. To that end I created a variable in UIBaseBean:

protected String toolbarDescription;

I also provided the setter and getter in UIBaseBean. In UIBaseBean's constructor I define the variable:

toolbarDescription = "fix me";

That definition is just so I know to override the variable in the backing bean for any particular page in my application. In my UserDetailBean I assign a new value to the String toolbarDescription. This value is displayed on the detail.xhtml page. Otherwise, the bean for my detail.xhtml page is very straightfoward, it gets and sets properties for the display of data in the form on the detail.xhtml page.

The detail page is set up so the navigation to it happens with a redirect, and the navigation away (when the commandButton is pressed) happens with a redirect. I have tried using faces-config navigation rules with and without redirects, and implicit navigation with and without redirects, but the UserDetailBean constructor is always called twice.

Oh, I set a breakpoint on the toolbarDescription variable in my UserDetailBean constructor, which stops the program twice: when the page is first called, and again after I press the commandButton on the detail page.

From what I've described, can anyone tell me why my constructor is being called twice? Did I design my bean incorrectly, or is the problem deeper in my application?

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);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

九命猫 2024-10-23 02:09:56

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

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

You need to remove the @RequestScoped and other related annotations from the UIBaseBean (and make it abstract).

Once that is done, you also need to fix the @ManagedProperty on #{param} to be either defined by <f:viewParam> or to be obtained by ExternalContext#getRequestParameterMap() instead. It's namely not possible to inject something which has a shorter scope into something which has a larger scope (because it's not clear which one should be injected since there can be more of them during the scope of the acceptor). JSF would throw an exception on that during bean's construction.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文