[英]JSF 2, Ajax, FacesException: java.lang.IllegalStateException
[英]java.lang.IllegalStateException: CDATA tags may not nest
我在JSF頁面中遇到了Ajax請求的問題。 當我單擊按鈕時,出現以下異常:
SEVERE: 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)
at javax.faces.context.PartialResponseWriter.startError(PartialResponseWriter.java:342)
at org.primefaces.context.PrimePartialResponseWriter.startError(PrimePartialResponseWriter.java:210)
at com.sun.faces.context.AjaxExceptionHandlerImpl.handlePartialResponseError(AjaxExceptionHandlerImpl.java:200)
at com.sun.faces.context.AjaxExceptionHandlerImpl.handle(AjaxExceptionHandlerImpl.java:123)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
我認為String
對象存在一些問題,因為當我對站點上顯示的JPA實體屬性進行硬編碼時,一切都很好。 但是,當從數據庫(PostgreSQL)中檢索實體時,它將引發上述異常。
JSF代碼:
<p:column>
<f:facet name="header">
Akcja
</f:facet>
<h:commandButton actionListener="#{mBDocumentMigration.actionEdit(object)}" value="Edytuj" rendered="#{mBDocumentMigration.editingObject == null}" >
<f:ajax render="@form" execute="@form" />
</h:commandButton>
<h:commandButton action="#{mBDocumentMigration.actionZapisz}" value="Zapisz" rendered="#{mBDocumentMigration.editingObject != null}" >
<f:ajax render="@form" execute="@this" />
</h:commandButton>
</p:column>
在渲染JSF響應期間,由於代碼中的錯誤而引發了異常。 但是,Mojarra卻無法使用內置的ajax異常處理程序正確處理此異常,從而導致了另一個您現在看到的異常,隱藏了有關原始異常的所有詳細信息。
仔細查看堆棧跟蹤。 從底部開始以跟蹤調用堆棧:
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
因此,它發生在渲染響應階段。 好的,請看下一行(上面的那一行):
at com.sun.faces.context.AjaxExceptionHandlerImpl.handle(AjaxExceptionHandlerImpl.java:123)
嘿,它已經通過Mojarra的內置ajax異常處理程序AjaxExceptionHandlerImpl
! 僅當ajax請求期間發生異常時才調用此方法。 好的,從下至上依次閱讀以下幾行:
at com.sun.faces.renderkit.html_basic.HtmlResponseWriter.startCDATA(HtmlResponseWriter.java:630)
at javax.faces.context.ResponseWriterWrapper.startCDATA(ResponseWriterWrapper.java:172)
at javax.faces.context.PartialResponseWriter.startError(PartialResponseWriter.java:342)
at org.primefaces.context.PrimePartialResponseWriter.startError(PrimePartialResponseWriter.java:210)
at com.sun.faces.context.AjaxExceptionHandlerImpl.handlePartialResponseError(AjaxExceptionHandlerImpl.java:200)
因此,它試圖將錯誤信息寫入ajax響應。 此信息必須放在CDATA塊中。 但是,啟動CDATA塊失敗如下,因為顯然已經打開了CDATA塊:
java.lang.IllegalStateException: CDATA tags may not nest
這又表明該異常是在編寫ajax響應期間發生的,最有可能是因為您正在使用getter方法執行業務邏輯,而該方法僅在生成HTML輸出時才被調用。 因此,該過程很可能如下所示:
<f:ajax render="some">
(或<p:ajax update="some">
),它需要使用在CDATA塊內生成的HTML輸出創建一個<update id="some">
XML 塊。 (以使XML輸出在語法上有效)。 因此,需要啟動一個CDATA塊。 value
屬性。 AjaxExceptionHandlerImpl
被觸發。 AjaxExceptionHandlerImpl
需要將異常/錯誤詳細信息寫入響應。 但是,它沒有檢查響應是否已經寫入。 它盲目地嘗試打開一個CDATA塊,該塊又因已打開而失敗了。 它引發了您所看到的異常,從而隱藏了它嘗試處理的真正基礎異常的所有詳細信息。 如您所見,問題有兩個:
AjaxExceptionHandlerImpl
應該已經檢查/驗證了響應的狀態。 如果您用一個立即打印堆棧跟蹤信息的自定義程序替換了Mojarra的內置ajax異常處理程序,或者使用能夠檢測和清除半熟的ajax響應的OmniFaces FullAjaxExceptionHandler
替換了Mojarra的內置ajax異常處理程序,那么它最終將揭示並顯示由您的錯誤引起的真正底層碼。 如前所述,這很可能是由使用吸氣劑方法執行業務邏輯引起的,這是一個壞習慣 。
我遇到了與您同樣的問題,當我使用支持bean中的自動完成組件進行綁定時,它工作正常。
<p:autoComplete id="autocomplete" binding="#{searchBean.compui}" title="Find" value="#{searchBean.searchfor}" forceSelection="false" queryDelay="30" dropdown="true" maxResults="20" emptyMessage="None" completeMethod="#{searchBean.complete}" style="width: 90%;"/>
<p:commandButton id="cmdsearch" value="#{msg.search}" action="#{searchBean.search}" update="tblprocresults" icon="ui-icon-zoomin"/>
並在支持豆中
private AutoComplete compui;
//compui is initialized when bean is constructed
public AutoComplete getCompui() {
return compui;
}
public void setCompui(AutoComplete compui) {
this.compui = compui;
}
CDATA問題不是PrimeFaces問題,而是與負責提供部分輸出的JSF實現有關。 用它的JSF屬性替換;)
如果還看到java.lang.ClassCastException: com.sun.faces.facelets.compiler.UIInstructions cannot be cast to org.primefaces.component.tree.UITreeNode
在服務器日志中java.lang.ClassCastException: com.sun.faces.facelets.compiler.UIInstructions cannot be cast to org.primefaces.component.tree.UITreeNode
,請添加
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
到/WEB-INF/web.xml
僅僅考慮一些東西,有時這可能是一個非常愚蠢的錯誤。
例如,如果我忘記在xhtml頁面使用的其中一個bean中初始化ArrayList,有時會收到相同的錯誤消息:
我會這樣做:
List<String> myList;
但是忘記這樣做:
myList = new ArrayList();
因此,還有另一件事要考慮,請確保您已做好所有整理工作(確保變量已初始化/填充等)。
我在Tomcat 7中擺脫類似執行的經驗是:如果在jsf中調用方法,則即使沒有參數,也必須添加()。
如果使用碼頭,則不會出現此異常,但不會出現
編輯:即使消除了此異常,它給另一個異常:
java.lang.NoSuchMethodError: javax.el.ELResolver.invoke(Ljavax/el/ELContext;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object;
經過研究,我發現Tomcat 7本身帶來了EL依賴關系,因此pom.xml中的其他任何依賴關系
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
應將其取下以避免混合。
之后,您必須通過在Eclipse中運行為tomcat7:run
來啟動tomcat7,而不是默認情況下會啟動tomcat 6的tomcat:run
。
我的環境:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.