java.lang.IllegalStateException:CDATA标签可能不会嵌套(java

2019-06-17 17:08发布

我有一个问题,在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实体属性,那么一切都OK。 然而,当该实体是从数据库(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>

Answer 1:

有渲染造成的代码中的错误的JSF反应过程中被抛出的异常。 然而,钻嘴鱼科又未能妥善处理这一异常,并内置AJAX异常处理程序,从而导致另一个异常,你现在看到的,躲着走对原以外的所有细节。

看看堆栈跟踪近。 在底部开始跟踪调用堆栈:

at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)

因此,它的发生期间显示响应阶段。 好吧,看看下一行(一个上面):

at com.sun.faces.context.AjaxExceptionHandlerImpl.handle(AjaxExceptionHandlerImpl.java:123)

嘿,这是通过钻嘴鱼科的内置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">它需要创建一个<update id="some">与内部生成的HTML输出XML块CDATA块 (保持XML输出语法有效)。 因此,一个CDATA块需要启动。
  4. 在产生HTML输出到CDATA块,所有渲染时间EL表达式进行求值,包括value的所有UI组件的属性。
  5. 冥冥之中,EL表达式背后,吸气扔造成在自己的代码中的错误的异常。
  6. JSF及时制止生成HTML输出,并没有关闭CDATA块。 HTTP响应包含halfbaked数据。
  7. AjaxExceptionHandlerImpl被触发。
  8. AjaxExceptionHandlerImpl需要写异常/错误详细的回应。 然而,它并没有检查,如果响应已经写入。 它盲目地尝试打开一个CDATA块,又失败了,因为它已经打开。 它扔了你所看到的例外,躲着走对真正的根本例外它试图处理所有的细节。

正如你所看到的,这个问题有两方面:

  1. JSF渲染器不应该离开halfbaked的响应。
  2. 钻嘴鱼科的AjaxExceptionHandlerImpl应该检查/检验响应的状态。

如果您通过更换钻嘴鱼科的内置AJAX异常处理程序自定义的其立即打印堆栈跟踪 ,或由OmniFaces FullAjaxExceptionHandler ,它能够检测和清除halfbaked Ajax响应 ,那么它最终将揭示和展现真正由一个bug底层引起的码。 正如前面所说的,它是最有可能造成在一个getter方法,这是一种不好的做法,执行业务逻辑 。



Answer 2:

我有同样的问题,因为你,当我使用自动完成组件与支持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"/>

而在后台bean

private AutoComplete compui;
//compui is initialized when bean is constructed
    public AutoComplete getCompui() {
            return compui;
        }

        public void setCompui(AutoComplete compui) {
            this.compui = compui;
        }


Answer 3:

CDATA问题不是一个PrimeFaces问题,而是关系到JSF执行谁负责提供部分输出的。 通过它的JSF财产更换;)



Answer 4:

如果你也看到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



Answer 5:

只是在扔东西要考虑为好,有时也可以是一个真正的骨为首的错误。

例如,有时我会,如果我忘了在我的豆谓之XHTML页面使用的一个初始化一个ArrayList收到此相同的错误信息:

我这样做:

List<String> myList;

但是忘记这样做:

myList = new ArrayList();

因此,正如其他的事情想想,确保你已经照顾你所有的看家的(确保变量初始化/填充,等...)



Answer 6:

我的经验,以摆脱的Tomcat 7 simliar execption的是:如果你调用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>

768,16被移除,以避免在混合。

在这之后,你必须开始通过运行tomcat7为- tomcat7:run ,而不是在Eclipse中tomcat:run其默认启动Tomcat的6。

我的环境:

  • Eclipse的开普勒
  • JDK 1.7.0_45
  • Maven的3.1.1


文章来源: java.lang.IllegalStateException: CDATA tags may not nest