有时,当使用<h:commandLink>
, <h:commandButton>
或<f:ajax>
,与标签关联的action
, actionListener
或listener
方法根本不会被调用。 或者,不使用提交的UIInput
值更新Bean属性。 javascript
有哪些可能的缘由和解决方案? html
尽管个人回答并不是100%适用,可是大多数搜索引擎都将其做为第一匹配,但我仍是决定将其发布: java
若是您使用的是PrimeFaces (或相似的API) p:commandButton
或p:commandLink
,则可能忘记了将process="@this"
显式添加到命令组件中。 jquery
如《 PrimeFaces用户指南》第3.18节所述, process
和update
的默认值均为@form
,这与您可能从纯JSF f:ajax
或RichFaces中得到的默认值彻底相反,它们是execute="@this"
和render="@none"
分别为render="@none"
。 git
只是花了我很长一段时间才能找到答案。 (...并且我认为使用不一样于JSF的默认值至关不明智!) github
我本身陷入了这个问题,并找到了致使该问题的另外一个缘由。 若是在后备bean中没有用于* .xhtml中使用的属性的setter方法,那么就不会调用该操做。 web
每当UICommand
组件( <h:commandXxx>
, <p:commandXxx>
等)没法调用关联的操做方法,或者UIInput
组件( <h:inputXxx>
, <p:inputXxxx>
等)没法处理提交值和/或更新模型值,而且在服务器日志中看不到任何可谷歌搜索的异常和/或警告,一样,按照JSF ajax请求中的异常处理配置ajax异常处理程序时,也没有设置在web.xml
中的上下文参数下面, ajax
<context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param>
而且您也没有在浏览器的JavaScript控制台中看到任何可谷歌搜索的错误和/或警告(按Chrome / Firefox23 + / IE9 +中的F12打开Web开发人员工具集,而后打开“ 控制台”选项卡),而后在可能的缘由列表下进行工做。 数据库
UICommand
和UIInput
组件必须放置在UIForm
组件内,例如<h:form>
(所以不是普通的HTML <form>
),不然什么也不能发送到服务器。 UICommand
组件也不能具备type="button"
属性,不然它将是一个无效按钮,仅对JavaScript onclick
有用。 另请参见如何在JSF bean中发送表单输入值和调用方法,而且<h:commandButton>不会启动回发 。 api
您不能相互嵌套多个UIForm
组件。 这在HTML中是非法的。 浏览器行为未指定。 小心包含文件! 您能够并行使用UIForm
组件,可是在提交期间它们不会相互处理。 您还应该提防“上帝形态”反模式; 确保您不会无心间以相同的形式处理/验证全部其余(不可见的)输入(例如,具备与输入相同形式的隐藏对话框的隐藏对话框)。 另请参见如何在JSF页面中使用<h:form>? 单一表格? 多种形式? 嵌套表格? 。
没有应该发生UIInput
值验证/转换错误。 您可使用<h:messages>
显示任何输入特定的<h:message>
组件未显示的<h:message>
。 不要忘记在<f:ajax render>
包含<h:messages>
的id
(若是有的话),以便在ajax请求中也将对其进行更新。 另请参见当按下p:commandButton时,h:messages不显示消息 。
若是UICommand
或UIInput
元件放置等的迭代组件内<h:dataTable>
, <ui:repeat>
等,则须要确保彻底相同的value
的迭代成分的过程当中应用的请求的值相被保存表单提交请求。 JSF将在其上重申以找到单击的连接/按钮和提交的输入值。 将bean放在视图范围内和/或确保将数据模型加载到bean的@PostConstruct
中(所以不在getter方法中!)应该能够修复它。 另请参见如何以及什么时候从数据库中为h:dataTable加载模型 。
若是动态源(如<ui:include src="#{bean.include}">
包含UICommand
或UIInput
组件,则须要确保在视图期间保留彻底相同的#{bean.include}
值。表单提交请求的构建时间。 JSF将在构建组件树期间从新执行它。 将bean放在视图范围内和/或确保将数据模型加载到bean的@PostConstruct
中(所以不在getter方法中!)应该能够修复它。 另请参阅如何经过导航菜单Ajax刷新动态包含内容? (JSF SPA) 。
在表单提交请求的应用请求值阶段,组件及其全部父项的rendered
属性以及任何父项<c:if>
/ <c:when>
的test
属性不该评估为false
。 JSF将对其进行从新检查,以做为防范被篡改/被黑客入侵的保护措施的一部分。 将负责该条件的变量存储在@ViewScoped
Bean中,或者确保您在@RequestScoped
Bean的@PostConstruct
中正确地@ViewScoped
初始化了该条件,能够对其进行修复。 这一样适用于组件的disabled
属性,在应用请求值阶段,该属性不该评估为true
。 另请参见未调用JSF CommandButton操做,而且不处理有条件呈现的组件中的Form Submit 。
该onclick
的属性UICommand
组件和onsubmit
的属性UIForm
组件不该该返回false
或致使JavaScript错误。 若是<h:commandLink>
或<f:ajax>
也应该在浏览器的JS控制台中没有可见的JS错误。 一般,使用Google搜索确切的错误消息已经能够给您答案。 另请参见将jQuery添加到PrimeFaces会致使Uncaught TypeErrors 。
若是您经过JSF 2.x <f:ajax>
或例如PrimeFaces <p:commandXxx>
使用Ajax,请确保主模板中有<h:head>
而不是<head>
。 不然,JSF将没法自动包含包含Ajax函数的必要JavaScript文件。 这将致使浏览器的JS控制台出现JavaScript错误,例如“未定义mojarra”或“未定义PrimeFaces”。 另请参见与f:ajax和ui:repeat一块儿使用时,不会调用h:commandLink actionlistener 。
若是您使用的是Ajax,而且提交的值最终为null
,那么请确保感兴趣的UIInput
和UICommand
组件被<f:ajax execute>
或例如<p:commandXxx process>
覆盖,不然它们将不会被'将被执行/处理。 另请参见在将<f:ajax>添加到<h:commandButton>并了解PrimeFaces流程/更新和JSF f:ajax执行/渲染属性 时,模型中未更新提交表单值 。
若是提交的值仍然最终为null
,而且您正在使用CDI管理Bean,请确保从正确的包中导入范围注释,不然CDI将默认为@Dependent
,这样能够在每次评估时有效地从新建立Bean。 EL表达式 另请参见@SessionScoped bean一直释放做用域并一直从新建立,字段变为空,而且JSF 2应用程序中的默认Managed Bean Scope是什么?
若是具备UICommand
按钮的<h:form>
的UICommand
是事先由来自同一页面中另外一种表单的ajax请求呈现/更新的,则第一个操做在JSF 2.2或更早版本中将始终失败。 第二步和后续操做将起做用。 这是由视图状态处理中的错误引发的,该错误报告为JSF规范问题790 ,当前已在JSF 2.3中修复。 对于较旧的JSF版本,您须要在<f:ajax>
的render
中显式指定<h:form>
的ID。 另请参见h:commandButton / h:commandLink在第一次单击时不起做用,仅在第二次单击时起做用 。
若是<h:form>
设置了enctype="multipart/form-data"
以支持文件上传,那么您须要确保至少使用JSF 2.2,或者要确保负责该工做的servlet过滤器解析multipart / form-data请求的配置正确,不然FacesServlet
最终将根本没有任何请求参数,从而没法应用请求值。 如何配置此类过滤器取决于所使用的文件上传组件。 对于“战斧” <t:inputFileUpload>
,请检查此答案 ;对于PrimeFaces <p:fileUpload>
,请检查此答案 。 或者,若是您实际上根本没有上传文件,请彻底删除该属性。
确保actionListener
的ActionEvent
参数是javax.faces.event.ActionEvent
,所以不是java.awt.event.ActionEvent
,这是大多数IDE建议的第一种自动完成选项。 若是使用actionListener="#{bean.method}"
则没有参数也是错误的。 若是您不想在方法中使用参数,请使用actionListener="#{bean.method()}"
。 或者,也许您其实是想使用action
而不是actionListener
。 另请参见action和actionListener之间的区别 。
确保例如经过调用FacesContext#renderResponse()
或FacesContext#responseComplete()
,请求-响应链中的PhaseListener
或任何EventListener
没有更改JSF生命周期以跳过调用操做阶段。
确保同一请求-响应链中没有Filter
或Servlet
以某种方式阻止了FacesServlet
的请求。
若是您使用的是PrimeFaces <p:dialog>
或<p:overlayPanel>
,请确保它们具备本身的<h:form>
。 由于,默认状况下,JavaScript将这些组件重定位到HTML <body>
末尾。 所以,若是他们最初坐在<form>
,那么如今他们将再也不坐在<form>
。 另请参阅p:commandbutton动做在p:dialog中不起做用
框架中的错误。 例如,当使用带有defaultLabel
属性的rich:calendar
UI元素(或在某些状况下,是rich:placeholder
子元素)时,RichFaces会出现“ 转换错误 ”。 当没有为日历日期设置任何值时,此错误阻止Bean方法被调用。 跟踪框架的错误能够经过从一个简单的工做示例开始并备份页面直到发现该错误来完成。
万一您仍然卡住,该进行调试了。 在客户端,按Web浏览器中的F12打开Web开发人员工具集。 单击控制台选项卡,以便查看JavaScript。 它应该没有任何JavaScript错误。 下面的屏幕快照是Chrome的示例,演示了在未声明<h:head>
的状况下提交启用<f:ajax>
按钮的状况(如以上第7点所述)。
单击网络选项卡以查看HTTP流量监视器。 提交表单并调查请求标题和表单数据以及响应正文是否符合预期。 下面的屏幕快照是一个来自Chrome的示例,该示例演示了一个简单表单的成功ajax提交,该表单具备一个<h:inputText>
和一个<h:commandButton>
以及一个<f:ajax execute="@form" render="@form">
。
(警告:当您在生产环境中从上述HTTP请求标头发布屏幕截图时,请确保对屏幕截图中的全部会话cookie进行加扰/模糊处理,以免会话劫持攻击!)
在服务器端,请确保服务器以调试模式启动。 将调试断点放在感兴趣的JSF组件的方法中,您但愿在处理表单提交期间调用该方法。 例如,若是使用UICommand
组件, UICommand#queueEvent()
;若是使用UIInput
组件, UICommand#queueEvent()
UIInput#validate()
。 只需逐步执行代码并检查流程和变量是否符合预期便可。 屏幕截图下方是Eclipse调试器的示例。
我还要提到与Primefaces的p:commandButton
有关的另外一件事!
当对服务器上须要执行的操做使用p:commandButton
,不能使用type="button"
由于它用于用于执行自定义javascript而不会引发ajax / non-ajax请求的按钮到服务器。
为此,您能够分配type
属性(默认值为"submit"
),也能够显式使用type="submit"
。
但愿这会对某人有所帮助!
最近,我遇到了一个问题,即便用IBM Extended Faces Components的JSF 1.2应用程序中没有调用UICommand。
我在数据表的行上有一个命令按钮(扩展版本,因此<hx:datatable>
),UICommand不会从表中的某些行触发(不会触发的行是大于默认行的行)显示屏尺寸)。
我有一个下拉组件,用于选择要显示的行数。 支持该字段的值在RequestScope
。 支持表自己的数据在某种ViewScope
(实际上,临时在SessionScope
)。
若是经过控件增长了行显示,该值也绑定到了数据表的rows
属性,则单击此命令后,因为此更改而显示的全部行都不会触发UICommand。
将此属性放在与表数据自己相同的做用域中能够解决此问题。
我认为在上面的BalusC#4中已经提到了这一点,但不只表值须要在View或Session范围内,并且还须要控制在该表上显示的行数的属性。