问题
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