ViewScope构造函数调用两次,不确定原因 [英] ViewScope constructor called twice, not sure why

查看:131
本文介绍了ViewScope构造函数调用两次,不确定原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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.

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

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;

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

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

toolbarDescription = "fix me";

这个定义就是这样我知道要覆盖我的任何特定页面的支持bean中的变量应用。在我的UserDetailBean中,我为String toolbarDescription分配了一个新值。该值显示在detail.xhtml页面上。否则,我的detail.xhtml页面的bean非常直接,它获取并设置了在detail.xhtml页面上显示数据的属性。

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.

详细信息页面已设置,因此导航到它时会发生重定向,导航离开(当按下commandButton时)会发生重定向。我尝试使用带有和不带重定向的faces-config导航规则,带有和不带重定向的隐式导航,但UserDetailBean构造函数总是被调用两次。

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.

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

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.

根据我的描述,任何人都可以告诉我为什么我的构造函数被调用两次?我是否错误地设计了bean,或者我的应用程序中的问题是否更深?

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


推荐答案

你需要删除 @RequestScoped 以及来自 UIBaseBean 的其他相关注释(并使其 abstract )。

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

一旦完成,你还需要在<$ c $上修复 @ManagedProperty c>#{param} 要么由< f:viewParam> 定义,要么由 ExternalContext#获得相反,getRequestParameterMap()。这是不可能将具有较短范围的东西注入具有较大范围的东西(因为不清楚应该注入哪一个,因为在接受者的范围内可以有更多的注入)。在bean构建期间,JSF会抛出异常。

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.

这篇关于ViewScope构造函数调用两次,不确定原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆