【问题标题】:jsf2 viewscoped managed bean initiated several timesjsf2 viewscoped托管bean多次启动
【发布时间】:2013-02-01 12:17:09
【问题描述】:

我对视图范围 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。 提前致谢。

【问题讨论】:

    标签: jsf-2 cdi view-scope


    【解决方案1】:

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

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

    如果你有正确的@SessionScoped,至少对我来说,所指出的行为是完全未知的问题。

    还有:

    @Named(value = "adminLogView")
    

    您在此处给出的值是它的默认值。还不如跳过这样的设置值。

    祝你好运

    【讨论】:

      【解决方案2】:

      @javax.faces.bean.ViewScoped 不能与 CDI 一起使用。因此,您需要使用 SeamFaces 或 MyFaces CODI 才能从 viewscope 服务中受益。

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

      • CDI 在每个 bean 调用后触发一个事件 AfterBeanDiscovery
      • 您可以使用 CDI 扩展来@Observes此事件并添加您的上下文实现
      • 在您的作用域实现中,您可以:
        1. 使用 ContextualFacesContext ViewRoot Map 获取您的 bean,并在 每次 ajax 回调后返回它
        2. 如果找不到第一步中的 bean 名称,请使用 CreationalContextFacesContext ViewRoot Map 中创建它

      为了更深入的解释,我推荐这个链接:http://www.verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation-to-cdi/

      【讨论】:

      • 博文中的描述过于简单。作为开发人员,我更喜欢查看可用的代码。就像 Codi 或 DeltaSpike 中的那个。
      • 就个人而言,我只是需要在每次 ajax 回调后检索我的 bean,Steven Verborgh 的实现对我很有用,并进行了一些调整
      • 我就是这么说的。如果我能得到一些也涵盖特殊情况的东西,我不会关注只显示一半真相的博客。
      • 谢谢@darWhi 我想我应该发布一个使用 cdi 扩展的 viewscope 的完整实现
      猜你喜欢
      • 2013-11-20
      • 1970-01-01
      • 2014-02-24
      • 2016-12-26
      • 2012-08-27
      • 1970-01-01
      • 2012-11-08
      • 2011-03-03
      • 1970-01-01
      相关资源
      最近更新 更多