ajax – java.lang.IllegalStateException:CDATA标签可能不嵌套

前端之家收集整理的这篇文章主要介绍了ajax – java.lang.IllegalStateException:CDATA标签可能不嵌套前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在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>
在渲染由代码中的错误引起的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响应时发生异常,很可能是因为您在生成HTML输出时仅调用getter方法执行业务逻辑。所以这个过程最有可能如下:

> JSF进入RENDER_RESPONSE阶段。
> JSF需要生成HTML输出
>对于每个< f:ajax render =“some”> (或< p:ajax update =“some”>)),则需要创建< update id =“some”>在CDATA block之间生成的HTML输出的XML块(以保持XML输出在语法上有效)。所以需要启动一个CDATA块。
>将HTML输出生成到CDATA块中时,会对所有渲染时EL表达式进行求值,包括所有UI组件的value属性
>在某个地方,EL表达式后面的getter会抛出一个由你自己的代码中的错误引起的异常。
> JSF会立即停止生成HTML输出,并没有关闭CDATA块。 HTTP响应包含半记录数据。
> AjaxExceptionHandlerImpl被触发。
> AjaxExceptionHandlerImpl需要将异常/错误详细信息写入响应。但是,它没有检查响应是否已经被写入。它盲目地尝试打开一个CDATA块,由此它已经被打开了。它抛出了你看到的异常,隐藏了所有关于它试图处理的真正的底层异常的细节。

你可以看到,问题是双重的:

> JSF渲染器不应该让响应halfbaked。
> Mojarra的AjaxExceptionHandlerImpl应该已经检查/验证了响应的状态。

如果您用custom one which immediately prints the stack traceOmniFaces FullAjaxExceptionHandler which is capable of detecting and cleaning halfbaked ajax responses替换Mojarra的内置ajax异常处理程序,那么最终会显示显示代码中的错误引起的真正原因。如前所述,这很可能是performing business logic in a getter method,which is a bad practice造成的。

猜你在找的Ajax相关文章