commandButton / commandLink / ajax动作/侦听器方法未调用或输入值未设置/更新
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了commandButton / commandLink / ajax动作/侦听器方法未调用或输入值未设置/更新相关的知识,希望对你有一定的参考价值。
有时候,当使用<h:commandLink>
,<h:commandButton>
或<f:ajax>
时,与标签相关的action
,actionListener
或listener
方法根本就没有被调用。或者,bean属性不会使用提交的UIInput
值更新。
有什么可能的原因和解决方案?
答案
介绍
每当UICommand
组件(<h:commandXxx>
,<p:commandXxx>
等)无法调用相关的操作方法,或者UIInput
组件(<h:inputXxx>
,<p:inputXxxx>
等)无法处理提交的值和/或更新模型值,并且您没有看到服务器日志中的任何googlable异常和/或警告,当你根据Exception handling in JSF ajax requests配置ajax异常处理程序时,也不是在web.xml
中设置下面的context参数时,
<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"
属性,否则它将是一个死按钮,只对JavaScriptonclick
有用。另见How to send form input values and invoke a method in JSF bean和<h:commandButton> does not initiate a postback。- 您不能将多个
UIForm
组件嵌套在一起。这在HTML中是非法的。浏览器行为未指定。注意包含文件!您可以并行使用UIForm
组件,但在提交期间它们不会互相处理。你也应该注意“神形”反模式;确保您不会无意中以相同的形式处理/验证所有其他(不可见)输入(例如,以相同的形式具有所需输入的隐藏对话框)。另见How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?。 - 不应该发生
UIInput
值验证/转换错误。您可以使用<h:messages>
显示任何特定于输入的<h:message>
组件未显示的消息。不要忘记在id
中加入<h:messages>
的<f:ajax render>
(如果有的话),这样它也会在ajax请求中更新。另见h:messages does not display messages when p:commandButton is pressed。 - 如果
UICommand
或UIInput
组件放在<h:dataTable>
,<ui:repeat>
等迭代组件中,那么您需要确保在表单提交请求的应用请求值阶段保留了与迭代组件完全相同的value
。 JSF将重申它以查找单击的链接/按钮和提交的输入值。将bean放在视图范围中和/或确保在bean的@PostConstruct
中加载数据模型(因此不在getter方法中!)应该修复它。另见How and when should I load the model from database for h:dataTable。 - 如果动态源(如
UICommand
)包含UIInput
或<ui:include src="#{bean.include}">
组件,则需要确保在表单提交请求的视图构建时间内保留完全相同的#{bean.include}
值。 JSF将在构建组件树期间重新执行它。将bean放在视图范围中和/或确保在bean的@PostConstruct
中加载数据模型(因此不在getter方法中!)应该修复它。另见How to ajax-refresh dynamic include content by navigation menu? (JSF SPA)。 - 组件及其所有父项的
rendered
属性以及任何父test
/<c:if>
的<c:when>
属性在表单提交请求的应用请求值阶段不应评估为false
。 JSF将重新检查它作为防范篡改/黑客攻击请求的一部分。在@ViewScoped
bean中存储负责该条件的变量,或者确保在@PostConstruct
bean的@RequestScoped
中正确预先初始化该条件应该修复它。这同样适用于组件的disabled
属性,在应用请求值阶段不应评估为true
。另见JSF CommandButton action not invoked和Form submit in conditionally rendered component is not processed。 onclick
组件的UICommand
属性和onsubmit
组件的UIForm
属性不应返回false
或导致JavaScript错误。在<h:commandLink>
或<f:ajax>
的情况下,在浏览器的JS控制台中也不会出现JS错误。通常谷歌搜索确切的错误信息已经给你答案。另见Adding jQuery to PrimeFaces results in Uncaught TypeError over all place。- 如果您通过JSF 2.x
<f:ajax>
使用Ajax或者例如PrimeFaces<p:commandXxx>
,确保你在主模板中有一个<h:head>
而不是<head>
。否则,JSF将无法自动包含包含Ajax函数的必要JavaScript文件。这将导致JavaScript错误,例如“mojarra未定义”或浏览器的JS控制台中未定义“PrimeFaces”。另见h:commandLink actionlistener is not invoked when used with f:ajax and ui:repeat。 - 如果您正在使用Ajax,请确保
UIInput
涵盖的UICommand
和<f:ajax execute>
组件或<p:commandXxx process>
,否则他们将不会被执行/处理。另见Submitted form values not updated in model when adding <f:ajax> to <h:commandButton>和Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes。 - 如果具有
<h:form>
按钮的UICommand
的父级预先由来自同一页面中的另一个表单的ajax请求呈现/更新,则第一个操作将始终失败。第二个及后续操作将起作用。这是由视图状态处理中的错误引起的,该错误报告为JSF spec issue 790并且当前计划在JSF 2.3中修复。对于较旧的JSF版本,您需要在<h:form>
的render
中明确指定<f:ajax>
的ID。另见h:commandButton/h:commandLink does not work on first click, works only on second click。 - 如果
<h:form>
设置了enctype="multipart/form-data"
以支持文件上载,那么您需要确保至少使用JSF 2.2,或者正确配置负责解析multipart / form-data请求的servlet过滤器,否则FacesServlet
最终将不会获得任何请求参数,因此无法应用请求值。如何配置此类过滤器取决于正在使用的文件上载组件。对于Tomahawk<t:inputFileUpload>
,检查this answer和PrimeFaces<p:fileUpload>
,检查this answer。或者,如果您实际上根本没有上传文件,则完全删除该属性。 - 确保
ActionEvent
的actionListener
参数是javax.faces.event.ActionEvent
,因此不是java.awt.event.ActionEvent
,这是大多数IDE建议的第一个自动完成选项。如果你使用actionListener="#{bean.method}"
,没有争论也是错误的。如果您不想在方法中使用参数,请使用actionListener="#{bean.method()}"
。或许你真的想用action
而不是actionListener
。另见Differences between action and actionListener。 - 确保请求 - 响应链中没有
PhaseListener
或任何EventListener
已更改JSF生命周期以跳过调用操作阶段,例如调用FacesContext#renderResponse()
或FacesContext#responseComplete()
。 - 确保同一请求 - 响应链中没有
Filter
或Servlet
以某种方式阻止了对FacesServlet
的请求。 - 框架中的错误。例如,当使用带有以上是关于commandButton / commandLink / ajax动作/侦听器方法未调用或输入值未设置/更新的主要内容,如果未能解决你的问题,请参考以下文章
Primefaces commandLink有效,但commandButton无效[重复]
h:commandButton 在 h:dataTable 中不起作用