jsf2 viewscoped托管bean多次启动

时间:2013-02-16 17:28:28

标签: jsf-2 cdi view-scope

我对view scoped bean有一个问题。我知道这是常见的问题,但我得不到正确的答案。我有一个数据表,负责在用户输入搜索某些条件时显示搜索结果。 这是xhtml:

<html   xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns="http://www.w3.org/1999/xhtml"

    xmlns:p="http://primefaces.org/ui">


<h:panelGroup id ="adminReportLogList">

<p:dataTable value="#{adminLogView.lazyModelReport}" var="model" id="reportLogList" lazy="true" paginator="true" rows="20" paginatorAlwaysVisible="false" paginatorPosition="bottom" emptyMessage="emppty list" styleClass="dtable" style="table-layout: fixed; width: 100%"
             paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15,20">

    <p:column headerText="Report number" sortBy="#{model.reportNumber}">
        <h:outputText value="#{model.reportLogId}"/>
    </p:column>
    <p:column headerText="Report date" sortBy="#{model.reportDate}">
            <h:outputText value="#{model.reportDate}">
                <f:convertDateTime pattern="yyyy/MM/dd hh:mm:ss"/>
            </h:outputText>
    </p:column>
    <p:column headerText="Search date" sortBy="#{model.searchLogId.searchDate}">
        <h:outputText value="#{model.searchLogId.searchdate}">
                <f:convertDateTime pattern="yyyy/MM/dd hh:mm:ss"/>
            </h:outputText>
    </p:column>
    <p:column headerText="User name" sortBy="#{model.searchLogId.loginLogId.username}">
        <h:outputText value="#{model.searchLogId.loginLogId.username}"/>
    </p:column>
    <p:column headerText="Customer number" sortBy="#{model.customerId}">
        <h:outputText value="#{model.customerId.registernumber}"/>
    </p:column>
    <p:column headerText="Customer name" sortBy="#{model.customerId}">
        <h:outputText value="#{model.customerId.name}"/>
    </p:column>
</p:dataTable>

</h:panelGroup>
<br/>

// SEARCH PANEL
<p:panel>
    <h:panelGrid columns="3" styleClass="insGrid" id="reportLogSearchPanel">
        <h:outputText value="User: "/>
        <p:inputText id="reportLogSearchByUserName" value="#{adminLogView.searchUserName}">
            <p:watermark for="reportLogSearchByUserName" value ="Customer name"/>
        </p:inputText>
        <h:message for="reportLogSearchByUserName" id="msgReportLogSearchByUserName" styleClass="errorMessage"/>

        <h:outputText value="Customer id number: "/>
        <p:inputText id="reportLogSearchByCustomerName" value="#{adminLogView.searchCustomerName}">
            <p:watermark for="reportLogSearchByCustomerName" value="Customer id number"/>
        </p:inputText>
        <h:message for="reportLogSearchByCustomerName" id="msgReportLogSearchBySearchDate" styleClass="errorMessage"/>

        <h:outputText value="Report date "/>
        <p:inputText id="reportLogSearchByReportDate" value="#{adminLogView.searchReportDate}">
            <p:watermark for="reportLogSearchByReportDate" value="Report date YYYY/MM/DD"/>
        </p:inputText>
        <h:message for="reportLogSearchByReportDate" id="msgReportLogSearchByReportDate" styleClass="errorMessage"/>

        <h:panelGroup/>
        <h:commandButton value="Search" styleClass="btn" action="#{adminLogView.searchReport()}">
            <f:ajax render =":form:adminReportLogList :form:reportLogList" execute=":form:reportLogSearchPanel"/>
        </h:commandButton>

    </h:panelGrid>

</p:panel>

用于另一个xhtml中的标记,它是:/我认为在这种情况下不是原因/

<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
                template="./../templates/admin_main.xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:p="http://primefaces.org/ui">

    <ui:define name="content">
        <h:panelGroup id="include">
        <ui:include src="#{adminLogView.page}.xhtml"/>
        </h:panelGroup>
    </ui:define>

</ui:composition>

这是我的豆子

@Named(value = "adminLogView")
@ViewScoped
public class AdminLogView implements Serializable{
    @EJB
    private LogServiceLocal logService;
    private List<Reportlog> ReportLogList;

    String page = "reportLog";
    LazyDataModel<Reportlog> lazyModelReport;
    LazyDataModel<Loginlog>  lazyModelLogin;
    LazyDataModel<Searchlog> lazyModelSearch;

    String searchCustomerName;
    String searchUserName;
    String searchReportDate;


    @PostConstruct
    public void init(){

        this.lazyModelReport = new LazyReportLogDataModel(this.logService);
    }

    public void searchReport(){
        Map<String, String> filter = new HashMap<String, String>();
        if(this.searchCustomerName != null && !this.searchCustomerName.isEmpty())
            filter.put("customerName", this.searchCustomerName);
        if(this.searchReportDate != null && !this.searchReportDate.isEmpty())
            filter.put("reportDate", this.searchReportDate);
        if(this.searchUserName != null && !this.searchUserName.isEmpty())
            filter.put("userName", this.searchUserName);



        this.lazyModelReport.load(0, 30, null, SortOrder.UNSORTED, filter);

    }
}

当我们导航到上面的页面时,多次调用@postConstruct方法,即使使用sessionScoped也是如此。即使我们在同一视图中单击搜索按钮,也会再次初始化bean。只有RequestScope正常工作。 我有误解或忘记了吗? PS。 提前致谢。

2 个答案:

答案 0 :(得分:2)

你有正确的SessionScoped吗? javax.enterprise.context.SessionScoped

你是否在类路径上有Myfaces CODI或任何其他适配器?否则@ViewScoped具有未记录的行为,因为它是JSF-2范围。

如果你有正确的@SessionScoped,那么至少对我来说这个行为是完全未知的问题。

此外:

@Named(value = "adminLogView")

您在此处提供的值是默认值。也可以像这样跳过设定值。

祝你好运

答案 1 :(得分:2)

@ javax.faces.bean.ViewScoped无法使用CDI。因此,您需要使用SeamFaces或MyFaces CODI从视图范围服务中受益。

CDI提供了扩展来创建自己的范围,因此您可以实现上下文并使用@NormalScope来执行此操作。

  • CDI在每次调用bean之后触发事件 AfterBeanDiscovery
  • 您可以使用CDI扩展程序 @Observes 此事件并添加您的上下文实现
  • 在您的范围实施中,您可以:
    1. 使用上下文 FacesContext ViewRoot Map 获取您的名称,并在每次ajax回调后将其返回
    2. 如果未找到第一步中的bean名称在 FacesContext ViewRoot Map
    3. 中创建它,请使用 CreationalContext

要获得更深入的解释,我建议您使用此链接:http://www.verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation-to-cdi/