使用bean的方法对<h:selectbooleancheckbox>的结果时的PropertyNotFoundException

时间:2015-04-23 06:26:23

标签: ajax spring jsf primefaces

环境

  • PrimeFaces 5.1
  • Mojarra 2.2.2
  • Spring 4.0.2

当前代码

我有以下XHTML页面:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:p="http://primefaces.org/ui"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                template="/WEB-INF/pages/main/admin.xhtml">

    <ui:define name="contentBody">
        <p:dataTable widgetVar="weekdayTable"
                     value="#{weekdayList.countries}"
                     var="ctr"
                     styleClass="weekdaysManagementDatatable">

            <p:column width="100"
                      sortBy="#{ctr.desc}"
                      headerText="#{msg['page.admin.weekday.list.country']}">
                <h:outputText value="#{ctr.desc}" />
            </p:column>

            <c:forEach items="#{weekdayList.weekdays}" var="day">
                <c:set var="open" value="#{weekdayList.checkOpen(ctr.id, day.date)}"/>
                <p:column width="20" headerText="#{utils.dateToDayWeek(day.date)}">
                    <h:selectBooleanCheckbox value="#{open}">
                        <p:ajax listener="#{weekdayList.handleDay(ctr.id, day.id)}" />
                    </h:selectBooleanCheckbox>
                </p:column>
            </c:forEach>
        </p:dataTable>
    </ui:define>
</ui:composition>

关联的bean如下:

@Named("weekdayList")
@Scope("session")
public class AdminWeekdayListController implements Serializable {

    ...

    public boolean checkOpen(String ctrId, Date date) {
        Country ctr = countryDao.getById(ctrId);
        List<WeekDay> list = weekdaysMap.get(ctr);

        if (list == null) {
            return true;
        }

        WeekDay day = new WeekDay();
        day.setDate(date);

        for (WeekDay wd : list) {
            if (wd.compareTo(day) == 0) {
                return wd.isOpen();
            }
        }
        return true;
    }
}

我有另一个bean来维护当前页面以显示整个应用程序是用AJAX制作的。用户始终在同一页面上,内容是动态加载的。

问题

当我重新加载(F5)页面时,一切似乎都正常工作。 但是,如果我进行常规导航(AJAX加载),我有一个PropertyNotFoundException ......

这是堆栈跟踪:

SEVERE: javax.faces.component.UpdateModelException: javax.el.PropertyNotFoundException: /WEB-INF/pages/main/admin/weekdayList.xhtml @32,47 value="#{open}": /WEB-INF/pages/main/admin/weekdayList.xhtml @29,74 value="#{weekdayList.checkOpen(ctr.id, day.date)}": Property 'checkOpen' not found on type stomac.web.controller.AdminWeekdayListController
    at javax.faces.component.UIInput.updateModel(UIInput.java:867)
    at javax.faces.component.UIInput.processUpdates(UIInput.java:749)
    at org.primefaces.component.api.UIData.process(UIData.java:342)
    at org.primefaces.component.api.UIData.processChildren(UIData.java:323)
    at org.primefaces.component.api.UIData.processPhase(UIData.java:285)
    at org.primefaces.component.api.UIData.processUpdates(UIData.java:271)
    at org.primefaces.component.datatable.DataTable.processUpdates(DataTable.java:651)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1286)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1286)
    at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1286)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1286)
    at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1254)
    at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:769)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1125)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1059)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:497)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:248)
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:610)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:539)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.el.PropertyNotFoundException: /WEB-INF/pages/main/admin/weekdayList.xhtml @32,47 value="#{open}": /WEB-INF/pages/main/admin/weekdayList.xhtml @29,74 value="#{weekdayList.checkOpen(ctr.id, day.date)}": Property 'checkOpen' not found on type stomac.web.controller.AdminWeekdayListController
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:133)
    at javax.faces.component.UIInput.updateModel(UIInput.java:832)
    ... 36 more
Caused by: javax.el.PropertyNotFoundException: /WEB-INF/pages/main/admin/weekdayList.xhtml @29,74 value="#{weekdayList.checkOpen(ctr.id, day.date)}": Property 'checkOpen' not found on type stomac.web.controller.AdminWeekdayListController
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:133)
    at org.apache.el.parser.AstIdentifier.setValue(AstIdentifier.java:129)
    at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:260)
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
    ... 37 more
Caused by: javax.el.PropertyNotFoundException: Property 'checkOpen' not found on type stomac.web.controller.AdminWeekdayListController
    at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:245)
    at javax.el.BeanELResolver$BeanProperties.access$300(BeanELResolver.java:222)
    at javax.el.BeanELResolver.property(BeanELResolver.java:332)
    at javax.el.BeanELResolver.getType(BeanELResolver.java:82)
    at com.sun.faces.el.DemuxCompositeELResolver._getType(DemuxCompositeELResolver.java:215)
    at com.sun.faces.el.DemuxCompositeELResolver.getType(DemuxCompositeELResolver.java:242)
    at org.apache.el.parser.AstValue.setValue(AstValue.java:199)
    at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:260)
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
    ... 40 more

但是是什么让我认为问题不是来自我的bean,如果我从#{open}的值中移除<h:selectBooleanCheckbox/>它完全有效(除了没有选中复选框)我想要的方式):

<c:forEach items="#{weekdayList.weekdays}" var="day">
    <c:set var="open" value="#{weekdayList.checkOpen(ctr.id, day.date)}"/>
    <p:column width="20" headerText="#{utils.dateToDayWeek(day.date)}">
        #{open}
        <h:selectBooleanCheckbox value="true">
            <p:ajax listener="#{weekdayList.handleDay(ctr.id, day.id)}" />
        </h:selectBooleanCheckbox>
    </p:column>
</c:forEach>

正如您所见,我继续使用#{open},但未使用value内容。

问题

我错了什么?我错过了什么吗?有错误吗?

感谢。

2 个答案:

答案 0 :(得分:3)

所以...我找到了一个&#34;解决方案&#34;,并回答我自己的问题。

我为方法checkOpen添加了fakes getter和setter。所以bean看起来像这样:

@Named("weekdayList")
@Scope("session")
public class AdminWeekdayListController implements Serializable {

    ...

    public boolean getCheckOpen() {
        return true;
    }

    public void setCheckOpen(boolean b) {
    }

    public boolean checkOpen(String ctrId, Date date) {
        Country ctr = countryDao.getById(ctrId);
        List<WeekDay> list = weekdaysMap.get(ctr);

        if (list == null) {
            return true;
        }

        WeekDay day = new WeekDay();
        day.setDate(date);

        for (WeekDay wd : list) {
            if (wd.compareTo(day) == 0) {
                return wd.isOpen();
            }
        }
        return true;
    }
}

这样JSF认为checkOpen是有效(读/写)属性,但是调用checkOpen(String ctrId, Date date)。它从不称呼吸气剂或吸气剂......

如果有人能够解释这一点,我将感激不尽。如果有人有更好的解决方案,我正在倾听。

答案 1 :(得分:0)

它是Taghandler和UI组件的LifeCycle。

JSF中的JSTL-Tags不代表组件,并且在构建视图后永远不会成为组件树的一部分。

TagHandlers负责构建树,&#34;一旦他们完成了工作,他们就会过期&#34;。这意味着,它们仅在View Building阶段可用。另一方面,UI-Components在View Rendering Phase中运行。