我在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>
答案 0 :(得分:48)
在呈现代码中的错误导致的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 block内创建一个<update id="some">
XML块并生成HTML输出(以便在语法上保持XML输出)有效)。因此需要启动CDATA块。value
属性。AjaxExceptionHandlerImpl
已被触发。AjaxExceptionHandlerImpl
需要将异常/错误详细信息写入响应。但是,它没有检查响应是否已经写入。它盲目地试图打开一个CDATA块,因为它已经打开而失败了。它抛出了你所看到的异常,隐藏了它试图处理的真实底层异常的所有细节。正如您所看到的,问题是双重的:
AjaxExceptionHandlerImpl
应检查/验证回复状态。如果用custom one which immediately prints the stack trace或OmniFaces 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引起的。
答案 1 :(得分:0)
我遇到了与你相同的问题,当我使用来自支持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;
}
答案 2 :(得分:-2)
CDATA问题不是PrimeFaces问题,而是与负责提供部分输出的JSF实现有关。 替换为它的JSF属性;)
答案 3 :(得分:-2)
如果您还在服务器日志中看到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
答案 4 :(得分:-2)
只是要考虑一些事情,有时它可能是一个真正的骨头错误。
例如,如果我忘记在xhtml页面使用的某个bean中初始化一个ArrayList,有时我会得到同样的错误信息:
我会这样做:
List<String> myList;
但忘记这样做:
myList = new ArrayList();
因此,另外要考虑的是,确保您已经处理了所有内务管理(确保变量已初始化/填充等等)
答案 5 :(得分:-4)
我在Tomcat 7中摆脱simliar execption的经验是:如果你在jsf中调用一个方法,你将不得不添加(),即使它没有参数。
此异常但如果您使用的是jetty
则不会出现编辑:即使这个例外被删除,它还有另一个例外:
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中以Run as - tomcat7:run
启动tomcat7,而不是默认启动tomcat 6的tomcat:run
。
我的环境: