JSF Backing Bean构造函数多次调用

时间:2011-01-28 08:50:31

标签: jsf jsf-2 icefaces

我正在尝试使用JSF 2.0(过去几个月使用ICEfaces 1.8之后),并且我试图找出为什么在JSF 2.0中我的支持bean构造函数被多次调用。

bean应该在创建时实例化一次,但只要我单击commandButton,就会显示“Bean Initialized”文本,指示一个新的Bean对象被实例化。

facelet页面:

    <?xml version='1.0' encoding='UTF-8' ?>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">

    <h:body>
        <div id="content">
            <h:form id="form">
                <h:commandButton value="Toggle" action="#{bean.toggleShowMe}"/>
            </h:form>


            <h:panelGrid rendered="#{bean.showMe}">
                <h:outputText value="Show me!"/>
            </h:panelGrid>
        </div>
    </h:body>
</html>

支持bean:

@ManagedBean
@RequestScoped
public class Bean {
    private boolean showMe = false;

    public boolean isShowMe() {
        return showMe;
    }

    public void setShowMe(boolean showMe) {
        this.showMe = showMe;
    }

    public void toggleShowMe(){
        System.out.println(showMe);
        if(showMe==true){
            showMe=false;
        }else{
            showMe=true;
        }
    }
    /** Creates a new instance of Bean */
    public Bean() {
        System.out.println("Bean Initialized");
    }

}

就是这样。只是一个简单的测试。如果我使用ICEfaces 2.0并代替我使用的panelGrid,则会出现相同的行为:

<ice:panelPopup visible="#{bean.showMe}">

我很感激这里有任何帮助。我无法解释它。

更新:为了回应Aba Dov,我@SessionScoped bean,认为它不会在每次请求时调用构造函数并遇到相同的行为。我错过了什么?

4 个答案:

答案 0 :(得分:6)

您已将bean声明放在请求范围内,并且每次都通过命令按钮触发新的HTTP请求。确实会在每次请求时创建bean。

如果你想让bean一直存在于视图本身(就像IceFaces正在为所有ajax的东西做掩盖),那么你需要声明bean视图范围(这是JSF 2.0中的新特性)。

@ManagedBean
@ViewScoped
public class Bean implements Serializable {}

答案 1 :(得分:1)

在我的情况下,问题是我导入了“ javax.faces.bean.ViewScoped”,而不是导入了“ javax.faces.view.ViewScoped”。

希望它可以帮助某人。

答案 2 :(得分:0)

每次有来自页面的请求时都会调用bean。

当您单击<h:commandButton>提交表单并将请求发送到服务器

为了防止它,您可以使用<t:saveState><a4j:keepAlive>标记。

例如<a4j:keepAlive beanName="YourBean" />

这些标记将bean实例存储在组件树中。

还要确保您的班级implements Serializable。所以可以序列化

希望这有帮助

答案 3 :(得分:0)

bean应该在ViewScoped中。