簡體   English   中英

java.lang.IllegalStateException:CDATA標記可能不會嵌套

[英]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輸出時才被調用。 因此,該過程很可能如下所示:

  1. JSF進入RENDER_RESPONSE階段。
  2. JSF需要生成HTML輸出。
  3. 對於每個<f:ajax render="some"> (或<p:ajax update="some"> ),它需要使用在CDATA塊內生成的HTML輸出創建一個<update id="some"> XML 塊。 (以使XML輸出在語法上有效)。 因此,需要啟動一個CDATA塊。
  4. 在將HTML輸出生成到CDATA塊中時,將評估所有渲染時EL表達式,包括所有UI組件的value屬性。
  5. 在某個地方,EL表達式后面的吸氣劑引發了一個異常,該異常是由您自己的代碼中的錯誤引起的。
  6. JSF立即停止生成HTML輸出,並且沒有關閉CDATA塊。 HTTP響應包含未完成的數據。
  7. AjaxExceptionHandlerImpl被觸發。
  8. AjaxExceptionHandlerImpl需要將異常/錯誤詳細信息寫入響應。 但是,它沒有檢查響應是否已經寫入。 它盲目地嘗試打開一個CDATA塊,該塊又因已打開而失敗了。 它引發了您所看到的異常,從而隱藏了它嘗試處理的真正基礎異常的所有詳細信息。

如您所見,問題有兩個:

  1. JSF渲染器不應該將響應置之不理。
  2. Mojarra的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

我的環境:

  • 日蝕開普勒
  • JDK 1.7.0_45
  • Maven 3.1.1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM