commandButton/commandLink/ajax动作/侦听器方法未调用或输入值未设置/更新

Muh*_*edy 332 jsf action commandlink jsf-2 commandbutton

有时,使用时<h:commandLink>,<h:commandButton>或者<f:ajax>,在action,actionListenerlistener与标签相关的方法根本不被调用.或者,bean属性不会使用提交的UIInput值进行更新.

有什么可能的原因和解决方案?

Bal*_*usC 664

介绍

每当UICommand组件(<h:commandXxx>,<p:commandXxx>等)无法调用关联的操作方法,或UIInput组件(<h:inputXxx>,<p:inputXxxx>等)无法处理提交的值和/或更新模型值,并且您没有看到任何可搜索的异常和/或服务器日志中的警告,当您按照JSF ajax请求中的异常处理配置ajax异常处理程序时,也不会在下面的context参数中设置时web.xml,

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>
Run Code Online (Sandbox Code Playgroud)

并且您也没有在浏览器的JavaScript控制台中看到任何可搜索的错误和/或警告(按Chrome/Firefox23 +/IE9 +中的F12打开Web开发人员工具集,然后打开控制台选项卡),然后查看下面可能的原因列表.

可能的原因

  1. UICommand并且UIInput组件必须放在UIForm组件内,例如<h:form>(因此不是纯HTML <form>),否则什么都不能发送到服务器.UICommand组件也必须没有type="button"属性,否则它将是一个死按钮,仅对JavaScript有用onclick.另请参见如何发送表单输入值并在JSF bean中调用方法,<h:commandButton>不会启动回发.

  2. 您不能将多个UIForm组件嵌套在一起.这在HTML中是非法的.浏览器行为未指定.注意包含文件!您可以UIForm并行使用组件,但在提交期间它们不会互相处理.你也应该注意"神形"反模式; 确保您不会无意中以完全相同的形式处理/验证所有其他(不可见)输入(例如,以相同的形式具有所需输入的隐藏对话框).另请参见如何在JSF页面中使用<h:form>?单一形式?多种形式?嵌套表格?.

  3. UIInput应该发生的值验证/转换错误.您可以使用它<h:messages>来显示任何特定于输入的<h:message>组件未显示的消息.不要忘了包括id<h:messages><f:ajax render>,如果有的话,那么,这将是在Ajax请求以及更新.另请参阅h:按下p:commandButton时,消息不显示消息.

  4. 如果UICommandUIInput组件放在迭代组件(如<h:dataTable>,<ui:repeat>等)中,则需要确保value在表单提交请求的应用请求值阶段保留了完全相同的迭代组件.JSF将重申它以查找单击的链接/按钮和提交的输入值.将bean放在视图范围中和/或确保在bean中加载数据模型@PostConstruct(因此不在getter方法中!)应该修复它.另请参见如何以及何时从数据库为h:dataTable加载模型.

  5. 如果动态源包含UICommandUIInput组件<ui:include src="#{bean.include}">,则需要确保#{bean.include}在表单提交请求的视图构建时间内保留完全相同的值.JSF将在构建组件树期间重新执行它.将bean放在视图范围中和/或确保在bean中加载数据模型@PostConstruct(因此不在getter方法中!)应该修复它.另请参阅如何通过导航菜单ajax-refresh动态包含内容?(JSF SPA).

  6. rendered组件及其所有的父母和属性test任何父的属性<c:if>/ <c:when>不应计算为false在申请表格的请求值阶段提交请求.JSF将重新检查它作为防范篡改/黑客攻击请求的一部分.存储变量在负责的条件@ViewScoped豆或确保你正确preinitializing条件中@PostConstruct一个的@RequestScoped豆应该修复它.这同样适用于disabled组件的属性,true在应用请求值阶段期间不应评估该属性.另请参见未调用的JSF CommandButton操作,并且不处理有条件呈现的组件中的表单提交.

  7. onclick该属性UICommand组件和onsubmit该属性UIForm组件不应该返回false或导致JavaScript错误.应该在的情况下,<h:commandLink>或者<f:ajax>也可以在浏览器的JS控制台中没有JS错误.通常谷歌搜索确切的错误信息已经给你答案.另请参阅向PrimeFaces添加jQuery会导致所有位置出现未捕获的TypeError.

  8. 如果您通过JSF 2.x <f:ajax>或PrimeFaces 使用Ajax <p:commandXxx>,请确保您<h:head>在主模板中使用而不是<head>.否则,JSF将无法自动包含包含Ajax函数的必要JavaScript文件.这将导致JavaScript错误,例如"mojarra未定义"或浏览器的JS控制台中未定义"PrimeFaces".另请参见h:commandLink actionlistener与f:ajax和ui:repeat一起使用时不会被调用.

  9. 如果您正在使用Ajax,那么请确保所关注的组件nullUIInput组件都包含在内,UICommand例如<f:ajax execute>,否则它们将不会被执行/处理.另请参阅将<f:ajax>添加到<h:commandButton>了解PrimeFaces process/update和JSF f:ajax execute/render属性时未在模型中更新的已提交表单值.

  10. 如果预先通过来自同一页面中另一个表单的ajax请求呈现/更新<p:commandXxx process>带有null按钮的父级,则第一个操作将始终失败.第二个及后续操作将起作用.这是由视图状态处理中的错误引起的,该错误报告为JSF规范问题790并且当前计划在JSF 2.3中修复.对于老版本的JSF,你需要明确指定的标识@Dependent<h:form>UICommand.另请参见h:commandButton/h:commandLink在第一次单击时不起作用,仅在第二次单击时起作用.

  11. 如果<h:form>已经render设置为了支持文件上传,那么你需要确保你至少使用JSF 2.2,或者负责解析multipart/form-data请求的servlet过滤器是否正确配置,否则<f:ajax>意志最终根本没有获得请求参数,因此无法应用请求值.如何配置此类过滤器取决于正在使用的文件上载组件.对于Tomahawk <h:form>,请查看此答案,对于PrimeFaces enctype="multipart/form-data",请查看此答案.或者,如果您实际上根本没有上传文件,则完全删除该属性.

  12. 确保FacesServlet参数<t:inputFileUpload>是a <p:fileUpload>而不是ActionEvent,这是大多数IDE建议的第一个自动完成选项.如果你使用,没有争论也是错误的actionListener.如果您不想在方法中使用参数,请使用javax.faces.event.ActionEvent.或许你真的想用java.awt.event.ActionEvent而不是actionListener="#{bean.method}".另请参见action和actionListener之间的差异.

  13. 确保请求 - 响应链中没有actionListener="#{bean.method()}"或任何action已更改JSF生命周期以跳过调用操作阶段,例如调用actionListenerPhaseListener.

  14. 确保没有EventListenerFacesContext#renderResponse()在同一个请求 - 响应链中FacesContext#responseComplete()以某种方式阻止了请求.

  15. 框架中的错误.例如,当使用具有属性的UI元素(或者,在某些情况下,子元素)时,RichFaces具有" 转换错误 " .如果没有为日历日期设置任何值,则此错误会阻止调用bean方法.跟踪框架错误可以通过从一个简单的工作示例开始并重新构建页面直到发现错误来完成.FilterServletFacesServlet

  16. 如果您正在使用PrimeFaces <p:dialog>或a <p:overlayPanel>,请确保您没有遇到p:commandbutton action在p:dialog内部无效

调试提示

如果你仍然卡住,是时候调试了.在客户端,在webbrowser中按F12打开Web开发人员工具集.单击Console选项卡,以查看JavaScript conosle.它应该没有任何JavaScript错误.下面的屏幕截图是Chrome的一个示例,演示了<h:form>在未<body>声明的情况下提交启用按钮的情况(如上面第7点所述).

js控制台

单击" 网络"选项卡以查看HTTP流量监视器.提交表单并调查请求标题和表单数据以及响应正文是否符合预期.下面的截图是从Chrome中这表明一个单一的简单形式的成功的Ajax提交的例子<form>和一个<form>rich:calendar.

网络监视器

(警告:当您从生产环境中发布上述HTTP请求标头的屏幕截图时,请确保在屏幕截图中对任何会话cookie进行加扰/混淆,以避免会话劫持攻击!)

在服务器端,确保服务器以调试模式启动.将调试断点放在您期望在处理表单提交期间调用的感兴趣的JSF组件的方法中.例如,在defaultLabel组件的情况下,那将是rich:placeholder并且在<f:ajax>组件的情况下<h:head>.只需逐步执行代码并检查流和变量是否符合预期.下面的截图是Eclipse调试器的一个例子.

调试服务器

  • @pauloguedes我找不到任何说明f:view呈现表单的东西.我的理解是它只是一个容器.根据我的经验,f:view不呈现任何元素. (2认同)
  • @Kukeltje:那会抛出EL异常(答案中第1段已经涵盖) (2认同)

jba*_*ndi 52

如果你h:commandLink在里面h:dataTable有另一个原因h:commandLink可能不起作用:

绑定到的基础数据源h:dataTable也必须在单击链接时触发的第二个JSF生命周期中可用.

因此,如果底层数据源是请求作用域,则h:commandLink不起作用!

  • 这已经在我的答案的第4点中说明了. (7认同)
  • 好的,这对我来说并不完全清楚.我希望我的回答无论如何都有用,因为在我的情况下,至少我没有明确地处理UICommand/UIData."解决方案"是从请求范围到会话范围推广支持bean ... (2认同)

Kaw*_*awu 28

虽然我的答案不是100%适用,但大多数搜索引擎都认为这是第一次点击,我决定发布它:

如果您正在使用PrimeFaces(或某些类似的API),p:commandButton或者p:commandLink您可能忘记明确添加process="@this"到命令组件.

由于PrimeFaces用户指南中第3.18节规定,为默认值processupdate@form,这非常反对你可能期望从普通的JSF默认f:ajax或RichFaces的,这是execute="@this"render="@none"分别.

我花了很长时间才找到答案.(...我认为使用与JSF不同的默认值是相当不清楚的!)

  • 这可能是文档中的错误.删除`process ="@ this"`并添加`<p:messages autoUpdate ="true">`(或者只读取服务器日志以获取排队但未显示的消息),您会看到实际发生了转换/验证错误. (8认同)
  • PrimeFaces`process`的默认值是`@ form`.因此,如果不以这种方式调用动作,但使用`@ this`时,则很可能我的答案的第3点适用. (6认同)
  • 不能这样 我有一个`p:commandButton`,直到我添加`process =“ @ this”`时才调用actionListener方法。此外,《 PrimeFaces用户指南》明确列出了我在3.18和3.19节中提到的默认设置。它在这里:http://primefaces.googlecode.com/files/primefaces_users_guide_3_4.pdf ...也许默认值已更改? (2认同)

ake*_*lec 9

我想提一下有关Primefaces的事情p:commandButton!

当您使用a p:commandButton进行需要在服务器上执行的操作时,您无法使用,type="button"因为这是用于执行自定义javascript而不会向服务器发出ajax/non-ajax请求的Push按钮.

为此,您可以分配type属性(默认值为"submit"),也可以显式使用type="submit".

希望这会对某人有所帮助!


Dna*_*vir 5

我自己也遇到了这个问题,并发现了这个问题的另一个原因。如果您的支持 bean 中没有用于 *.xhtml 中使用的属性的 setter 方法,则根本不会调用该操作。

  • 它应该导致一个相当不言自明的“PropertyNotWritableException”。如果您没有看到它,也许您在没有适当的 ajax 异常处理程序的情况下触发了 ajax 请求,但您应该在服务器日志中看到它。 (5认同)
  • 直到我设置 p:commandButton 的 ajax="false" 后,它才显示该异常。 (3认同)

归档时间:

查看次数:

198689 次

最近记录:

6 年,1 月 前