我在h:表单内的a4j:ajax标签遇到麻烦时,在同一表单中存在rich:pickList或rich:orderingList。发生的情况是ajax请求没有完成,并且后台bean中的侦听器方法没有被触发。onbegin事件被触发,但oncomplete不会。这真的很奇怪。
如果我将组件更改为rich:select或其他类似的,ajax将正常工作。
这是我的一部分代码。
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.org/schema/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j"
template="layout/template.xhtml">
<ui:define name="body">
<h:form id="perfil" styleClass="edit">
<rich:panel>
<a4j:outputPanel id="outputPanel">
<s:decorate id="nomeField" template="layout/edit.xhtml">
<ui:define name="label">Nome</ui:define>
<h:inputText id="nome" size="100" maxlength="100"
value="#{perfilHome.instance.nome}">
<a4j:ajax event="blur" onbegin="alert('begin');"
oncomplete="alert('complete');" bypassUpdates="true" render="outputPanel"
listener="#{perfilHome.test()}" />
</h:inputText>
</s:decorate>
</a4j:outputPanel>
<s:decorate id="descricaoField" template="layout/edit.xhtml">
<ui:define name="label">Descrição</ui:define>
<h:inputTextarea id="descricao" required="true" cols="100" rows="4" value="#{perfilHome.instance.descricao}" />
</s:decorate>
<s:decorate id="permissoesField" template="layout/edit.xhtml">
<rich:pickList required="true" styleClass="picklist" style="border: none; background: transparent;"
collectionType="java.util.ArrayList" immediate="false"
id="permissaoPickList"
value="#{perfilHome.instance.permissoes}"
listWidth="165px" listHeight="100px" orderable="true">
<f:selectItems id="permissoesItens" value="#{perfilHome.listarPermissoes()}" var="permissao"
itemValue="#{permissao}" itemLabel="#{permissao.nome}" />
<s:convertEntity />
</rich:pickList>
</s:decorate> </rich:panel>
<div class="actionButtons">
<h:commandButton id="save" value="Salvar"
action="#{perfilHome.persist}" disabled="#{!perfilHome.wired}"
rendered="#{!perfilHome.managed}">
<s:conversationId />
</h:commandButton>
<h:commandButton id="update" value="Salvar"
action="#{perfilHome.update}" rendered="#{perfilHome.managed}">
<s:conversationId />
</h:commandButton>
<h:commandButton id="delete" value="Deletar"
action="#{perfilHome.remove}" immediate="true"
rendered="#{perfilHome.managed}" /> </div>
</h:form>
<s:button id="cancelEdit" value="Cancelar" propagation="end"
view="/Perfil.xhtml" rendered="#{perfilHome.managed}" />
<s:button id="cancelAdd" value="Cancelar" propagation="end"
view="/#{empty perfilFrom ? 'PerfilList' : perfilFrom}.xhtml"
rendered="#{!perfilHome.managed}" />
</ui:define>
</ui:composition>
正如我所说的,我只在pickList和orderingList中观察到这种行为。有人遇到过这样的问题吗?
我的第二个问题是,如果我把两个s:按钮在表单内,ajax也没有被触发。对此有什么解释吗?
我正在使用JSF 2.1.14 + RichFaces 4.2.3 + Seam 2.3.0
感谢更新01/14/2013。观察到之前没有注意到的堆栈跟踪。我认为视图状态丢失了。再次测试了许多组件,只注意到pickList和orderingList的问题。
Exception during request processing:
Caused by java.lang.NullPointerException with message: ""
com.sun.faces.context.PartialViewContextImpl.createPartialResponseWriter(PartialViewContextImpl.java:441)
com.sun.faces.context.PartialViewContextImpl.access$300(PartialViewContextImpl.java:71)
com.sun.faces.context.PartialViewContextImpl$DelayedInitPartialResponseWriter.getWrapped(PartialViewContextImpl.java:582)
javax.faces.context.PartialResponseWriter.startDocument(PartialResponseWriter.java:115)
com.sun.faces.context.AjaxExceptionHandlerImpl.handlePartialResponseError(AjaxExceptionHandlerImpl.java:199)
com.sun.faces.context.AjaxExceptionHandlerImpl.handle(AjaxExceptionHandlerImpl.java:123)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:397)
org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50)
org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
java.lang.Thread.run(Thread.java:722)
很可能您的<rich:pickList/>
转换失败,导致整个表单提交阻塞,原因很明显:您没有在列表中定义转换器,并且您正在尝试将复杂类型更新到支持bean。除非您的value
绑定是常规java类型而不是pojo,否则您必须在<f:selectItems/>
上实现和定义JSF转换器。尝试通过在视图中放置一个<h:messages/>
来显示验证/转换错误
这也是为什么建议将JSF组件分成较小的表单,而不是现在的庞大表单的一个很好的理由;使用更小的表单