JSF Backing Bean 构造函数被多次调用

发布于 2024-10-14 17:36:49 字数 1615 浏览 4 评论 0原文

我正在尝试 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

听风吹 2024-10-21 17:36:49

您已声明将 bean 放置在请求范围内,并且每次都通过命令按钮触发新的 HTTP 请求。事实上,bean 将会根据每个请求而创建。

如果您希望 bean 与视图本身一样长(就像 IceFaces 在所有 ajax 内容的幕后所做的那样),那么您需要声明 bean 视图范围(这是 JSF 2.0 中的新功能)。

@ManagedBean
@ViewScoped
public class Bean implements Serializable {}

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 {}
最美的太阳 2024-10-21 17:36:49

就我而言,问题是我导入了“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.

生死何惧 2024-10-21 17:36:49

每次有来自页面的请求时都会调用该 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 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

oО清风挽发oО 2024-10-21 17:36:49

该 bean 应该位于 ViewScoped 中。

The bean should be in the ViewScoped.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文