JSF Backing Bean constructor called multiple times

怎甘沉沦 提交于 2019-12-10 17:09:20

问题


I'm trying out JSF 2.0 (after using ICEfaces 1.8 for the past few months) and I'm trying to figure out why in JSF 2.0 my backing bean constructor gets called multiple times.

The bean is supposed to be instantiated once upon creation, but the "Bean Initialized" text shows up whenever I click the commandButton, indicating a new Bean object being instansiated.

The facelet page:

    <?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>

The backing 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");
    }

}

Thats all it is. Just a simple test. The same behaviour shows itself if I use ICEfaces 2.0 and in place of the panelGrid I use:

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

I'd appreciate any help here. I'm at a loss to explain it.

Update: In response to Aba Dov, I @SessionScoped the bean, figuring it wouldn't be calling the constructor upon each request and ran into the same behavior. What am I missing?


回答1:


You have declared the bean to be placed in the request scope and you're firing a new HTTP request everytime by the command button. Truly the bean will be created on every request.

If you want that the bean lives as long as the view itself (like as IceFaces is doing under the covers for all that ajax stuff), then you need to declare the bean view scoped (this is new in JSF 2.0).

@ManagedBean
@ViewScoped
public class Bean implements Serializable {}



回答2:


In my case the problem was I imported "javax.faces.bean.ViewScoped" instead of importing "javax.faces.view.ViewScoped".

Hope it could help someone.




回答3:


The bean is called every time there is a request from the page.

when you click the <h:commandButton> the form is submitted and a request is sent to the server

in order to prevent it you can use <t:saveState> or <a4j:keepAlive> tags for your been.

for example <a4j:keepAlive beanName="YourBean" />

those tags stores the bean instance in the component tree .

also make sure that your class implements Serializable. so it can be serialized

Hope this helps




回答4:


The bean should be in the ViewScoped.



来源:https://stackoverflow.com/questions/4826377/jsf-backing-bean-constructor-called-multiple-times

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!