我对 JSF 很陌生,并且想要构建一个复合组件,该组件将导出一个可以从复合组件用户 ajaxed 的事件。
按照http://www.ibm.com/developerworks/java/library/j-jsf2fu-0610/index.html中的说明, 我使用了composite:clientBehavior,如下所示:
<composite:interface>
<composite:attribute name="value" required="true"/>
<composite:attribute name="selection" required="true"/>
[.... some other composite:attributes]
<composite:facet name="header"/>
<composite:clientBehavior name="rowSelect" event="rowSelect" default="true" targets="#{cc.clientId}:cmpntVideos"/>
</composite:interface>
<composite:implementation>
<h:outputStylesheet library="css" name="VideoStatusTable.css" target="head" />
<div id="#{cc.clientId}">
<p:contextMenu for="cmpntVideos">
<p:menuitem value="#{cc.resourceBundleMap.VideoStatusTable_contextual_menu_edit}" icon="menu-edit"/>
<p:menuitem value="#{cc.resourceBundleMap.VideoStatusTable_contextual_menu_delete}" icon="menu-delete"/>
<p:menuitem value="#{cc.resourceBundleMap.VideoStatusTable_contextual_menu_abort}" icon="menu-abort"/>
<p:menuitem value="#{cc.resourceBundleMap.VideoStatusTable_contextual_menu_reenable}" icon="menu-reenable"/>
</p:contextMenu>
<p:dataTable id="cmpntVideos" var="video" value="#{cc.attrs.value}" rowKey="#{video.key}"
selection="#{cc.attrs.selection}" selectionMode="single" emptyMessage="#{cc.attrs.emptyValueListMsg}">
<composite:insertFacet name="header"/>
<p:column headerText="#{cc.resourceBundleMap.VideoStatusTable_contextual_table_title_video_id}" rendered="#{cc.attrs.showRoadName}">
#{video.humanReadableVideoId}
</p:column>
[.... many other column declaration]
<p:column headerText="#{cc.resourceBundleMap.VideoStatusTable_contextual_table_title_report_generation}" rendered="#{cc.attrs.showReportGeneration}" style="text-align: center;">
<f:facet name="header">
<h:graphicImage library="images" name="documents_24.png"/>
</f:facet>
<cmpnt:simpleProgressBar value="#{video.reportGenerationProgress}"/>
</p:column>
<f:facet name="footer">
<h:commandLink action="cc.attrs.refreshListener" style="float:right;">
<h:graphicImage library="images" name="button-rotate-cw_16.png"/>
<f:ajax render="cmpntVideos" execute="@this"/>
</h:commandLink>
</f:facet>
</p:dataTable>
</div>
</composite:implementation>
并以下列方式使用该组件:
<cmpnt:videoStatusTable id="VideoTransferStatusTable"
value="#{videoTransfer.tableModel}"
selection="#{videoTransfer.selectedTableReadyNotCompletelyTranferedVideo}"
showProcess="false"
showReportGeneration="false"
showValidation="false"
showDataOrganization="false"
>
<f:ajax event="rowSelect" listener="${videoTransfer.onVideoSelection}" render=":msgsArea"/>
</cmpnt:videoStatusTable>
但是当我运行它(并选择一行,触发 rowSelect 事件)时,我得到以下异常:
SEVERE: Error Rendering View[/private/AssetManager.xhtml]
javax.faces.FacesException: java.io.NotSerializableException: com.sun.faces.facelets.tag.jsf.core.AjaxHandler
at com.sun.faces.renderkit.ResponseStateManagerImpl.getViewState(ResponseStateManagerImpl.java:137)
at javax.faces.application.StateManager.getViewState(StateManager.java:555)
[...]
Caused by: java.io.NotSerializableException: com.sun.faces.facelets.tag.jsf.core.AjaxHandler
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at java.util.ArrayList.writeObject(ArrayList.java:570)
[...]
WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalStateException: CDATA tags may not nest
at com.sun.faces.renderkit.html_basic.HtmlResponseWriter.startCDATA(HtmlResponseWriter.java:630)
at javax.faces.context.ResponseWriterWrapper.startCDATA(ResponseWriterWrapper.java:172)
当我删除 ajax 标记时,该组件工作正常(尽管没有某些功能)。
我使用 Glassfish 3.1.2。谁能帮我理解这里发生了什么?
谢谢