JSF Backing Bean 构造函数被多次调用
我正在尝试 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,我对 bean 进行了@SessionScoped,认为它不会在每个请求时调用构造函数并遇到相同的行为。我缺少什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您已声明将 bean 放置在请求范围内,并且每次都通过命令按钮触发新的 HTTP 请求。事实上,bean 将会根据每个请求而创建。
如果您希望 bean 与视图本身一样长(就像 IceFaces 在所有 ajax 内容的幕后所做的那样),那么您需要声明 bean 视图范围(这是 JSF 2.0 中的新功能)。
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).
就我而言,问题是我导入了“javax.faces.bean.ViewScoped”而不是导入“javax.faces.view.ViewScoped”。
希望它可以帮助别人。
In my case the problem was I imported "javax.faces.bean.ViewScoped" instead of importing "javax.faces.view.ViewScoped".
Hope it could help someone.
每次有来自页面的请求时都会调用该 bean。
当您单击
时,表单将被提交并向服务器发送请求,为了防止这种情况,您可以使用
或
标签。例如
这些标签将 bean 实例存储在组件树中。
还要确保您的类
实现可序列化
。所以可以序列化希望这有帮助
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 serverin 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 serializedHope this helps
该 bean 应该位于 ViewScoped 中。
The bean should be in the ViewScoped.