反复实例化@SessionScoped bean [英] @SessionScoped bean instantiated over and over

查看:39
本文介绍了反复实例化@SessionScoped bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用PrimeFaces 5.10,JSF 2和Wildfly,我试图使我的xhtml页面与具有PF poll组件的@SessionScoped bean的单个实例进行交互.每次轮询调用bean方法时,都会创建一个新的bean实例.我已经尝试过@ViewScoped和@SessionScoped,但行为没有变化.我注意到了其他类似的问题,但是还没有看到我能够实现的解决方案.

我知道println并不是显示方法调用顺序的可靠方法,但是我正在使用它们来演示正在调用的方法,而且似乎init()方法一遍又一遍地被调用,即使我有@PostConstruct,所以是新的实例.我什至正在打印"this",并且每次打印时都显示不同的哈希值.

它永远不会通过refreshTweets()中的if语句,因为stopPolling字段永远不会在正确的上下文中设置为false.

我以前曾遇到过这个问题,并且能够解决而不是解决它.如果有人对我在做什么错有任何想法,请告诉我.

以下是相关的xhtml代码:

<p:layoutUnit id="center" position="center" styleClass="dataBox">
    <h:form id="TwitterFeed">
        <p:panelGrid columns="2">
            <p:outputLabel value="Twitter topic to query: " />
            <p:inputText value="#{dataBean.tweetTopic}"/>
            <p:outputLabel value="Number of Twitter Results: " />
            <p:inputText value="#{dataBean.tweetCount}" />
            <p:commandButton value="Submit" action="#{dataBean.toggleRenderTweets}" update="tweets"/>
            <p:commandButton value="Polling" action="#{dataBean.togglePolling}" update="tweets"/>                           
        </p:panelGrid>
        <p:panel visible="#{dataBean.renderTweets}" id="tweets">
            <p:panelGrid columns="1">
                <p:dataTable id="twitterTable" value="#{dataBean.tweetList}" var="tweetStatus">
                    <p:columns value="#{dataBean.tweetColumns}" var="column" columnIndexVar="colIndex">
                        <f:facet name="header">
                            <h:outputText value="#{column.header}"/>
                        </f:facet>
                        <h:outputText value="#{tweetStatus[column.property]}"/>
                    </p:columns>
                </p:dataTable>
                <p:poll interval="10" listener="#{dataBean.refreshTweets}" update="twitterTable" widgetVar="tweetPoll" id="tweetPoll" autoStart="true"/>
            </p:panelGrid>
        </p:panel>
    </h:form>        
</p:layoutUnit>

相关的Bean代码如下:

import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.annotation.PostConstruct;
import java.io.Serializable;

@SessionScoped
@ManagedBean
public class DataBean implements Serializable {

    private List<TwitterStatusModel> tweetList;
    private boolean renderTweets;
    private boolean stopPolling;


    @PostConstruct
    public void init() {
        <<initialize fields>>
        stopPolling = true;
        System.out.println(this + " init()");
    }

    private void getTweets() {
       <<this method sets the List above tweetList>>
    }

    public void refreshTweets() {
        if (!stopPolling) {
            <<Method never passes the if statement because stopPolling is set to true in init()
        }

    public void togglePolling() {
        stopPolling = !(stopPolling);
        System.out.println(this + "Toggling polling - now " + stopPolling);
    }

解决方案

您应该使用@SessionScoped等的正确导入. 使用@ManagedBean,您需要javax.faces.bean.*而不是javax.enterprise.context或javax.faces.view

另请参见为什么会有不同的bean管理注释

Using PrimeFaces 5.10, JSF 2, and Wildfly, I am trying to get my xhtml page to interact with a single instance of a @SessionScoped bean with a PF poll component. Each time the poll calls the bean method, a new instance of the bean is created. I've tried @ViewScoped and @SessionScoped with no change in behavior. I've noticed other similar questions, but have not seen any with a solution I have been able to implement.

I know the println's are not a reliable way to show order of method calls, but i'm using them to merely demonstrate which methods are being called and it appears that the init() method gets called over and over, even though I have @PostConstruct, so it's new instantiations. I'm even printing out "this" and it's showing different hashes each time it prints.

It never gets through the if statement in refreshTweets() because the stopPolling field never gets set to false in the right context.

I've run into this problem before and have been able to work around it rather than solve it. If anyone has any ideas as to what I am doing wrong, please let me know.

Below is the relevant xhtml code:

<p:layoutUnit id="center" position="center" styleClass="dataBox">
    <h:form id="TwitterFeed">
        <p:panelGrid columns="2">
            <p:outputLabel value="Twitter topic to query: " />
            <p:inputText value="#{dataBean.tweetTopic}"/>
            <p:outputLabel value="Number of Twitter Results: " />
            <p:inputText value="#{dataBean.tweetCount}" />
            <p:commandButton value="Submit" action="#{dataBean.toggleRenderTweets}" update="tweets"/>
            <p:commandButton value="Polling" action="#{dataBean.togglePolling}" update="tweets"/>                           
        </p:panelGrid>
        <p:panel visible="#{dataBean.renderTweets}" id="tweets">
            <p:panelGrid columns="1">
                <p:dataTable id="twitterTable" value="#{dataBean.tweetList}" var="tweetStatus">
                    <p:columns value="#{dataBean.tweetColumns}" var="column" columnIndexVar="colIndex">
                        <f:facet name="header">
                            <h:outputText value="#{column.header}"/>
                        </f:facet>
                        <h:outputText value="#{tweetStatus[column.property]}"/>
                    </p:columns>
                </p:dataTable>
                <p:poll interval="10" listener="#{dataBean.refreshTweets}" update="twitterTable" widgetVar="tweetPoll" id="tweetPoll" autoStart="true"/>
            </p:panelGrid>
        </p:panel>
    </h:form>        
</p:layoutUnit>

The relevant bean code is below:

import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.annotation.PostConstruct;
import java.io.Serializable;

@SessionScoped
@ManagedBean
public class DataBean implements Serializable {

    private List<TwitterStatusModel> tweetList;
    private boolean renderTweets;
    private boolean stopPolling;


    @PostConstruct
    public void init() {
        <<initialize fields>>
        stopPolling = true;
        System.out.println(this + " init()");
    }

    private void getTweets() {
       <<this method sets the List above tweetList>>
    }

    public void refreshTweets() {
        if (!stopPolling) {
            <<Method never passes the if statement because stopPolling is set to true in init()
        }

    public void togglePolling() {
        stopPolling = !(stopPolling);
        System.out.println(this + "Toggling polling - now " + stopPolling);
    }

解决方案

You should use the correct imports of @SessionScoped etc. With a @ManagedBean you need the javax.faces.bean.* ones not the javax.enterprise.context ones or javax.faces.view

See also Why are there different bean management annotations

这篇关于反复实例化@SessionScoped bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆