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

发布于 2024-08-19 00:49:40 字数 292 浏览 3 评论 0 原文

有时,当使用 时,与标记关联的 actionactionListenerlistener 方法根本没有被调用。或者,bean 属性未使用提交的 UIInput 值进行更新。

出现这种情况的可能原因及解决方法有哪些?

Sometimes, when using <h:commandLink>, <h:commandButton> or <f:ajax>, the action, actionListener or listener method associated with the tag are simply not being invoked. Or, the bean properties are not updated with submitted UIInput values.

What are the possible causes and solutions for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

空城缀染半城烟沙 2024-08-26 00:49:41

我在调试 richfaces datatable 中的操作拒绝触发的问题时获得了很多乐趣。该表曾经在某个时候工作过,但没有明显的原因停止了。我千方百计,却发现我的 rich:datatable 使用了错误的 rowKeyConverter,它返回了 null,而 richfaces 很乐意将其用作行键。这阻止了我的 操作被调用。

I had lots of fun debugging an issue where a <h:commandLink>'s action in richfaces datatable refused to fire. The table used to work at some point but stopped for no apparent reason. I left no stone unturned, only to find out that my rich:datatable was using the wrong rowKeyConverter which returned nulls that richfaces happily used as row keys. This prevented my <h:commandLink> action from getting called.

紙鸢 2024-08-26 00:49:41

另一种可能性:如果症状是第一次调用有效,但后续调用无效,则您可能正在将 PrimeFaces 3.x 与 JSF 2.2 结合使用,详细信息如下:没有发送 ViewState

One more possibility: if the symptom is that the first invocation works, but subsequent ones do not, you may be using PrimeFaces 3.x with JSF 2.2, as detailed here: No ViewState is sent.

情定在深秋 2024-08-26 00:49:41

我通过将以下内容解决了问题

<h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>

<h:form>
     <h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>
</h:form>

I fixed my problem with placing the:

<h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>

In:

<h:form>
     <h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>
</h:form>
你爱我像她 2024-08-26 00:49:41

这是对我有用的解决方案。

<p:commandButton id="b1" value="Save" process="userGroupSetupForm"
                    actionListener="#{userGroupSetupController.saveData()}" 
                    update="growl userGroupList userGroupSetupForm" />

在这里,process="userGroupSetupForm" 属性对于 Ajax 调用是必需的。 actionListener 正在从 @ViewScope Bean 调用方法。还更新咆哮消息、数据表:userGroupList 和表单:userGroupSetupForm。

This is the solution, which is worked for me.

<p:commandButton id="b1" value="Save" process="userGroupSetupForm"
                    actionListener="#{userGroupSetupController.saveData()}" 
                    update="growl userGroupList userGroupSetupForm" />

Here, process="userGroupSetupForm" atrribute is mandatory for Ajax call. actionListener is calling a method from @ViewScope Bean. Also updating growl message, Datatable: userGroupList and Form: userGroupSetupForm.

(り薆情海 2024-08-26 00:49:41

对我有用的解决方案是将 在表单内部或表单数据所在的内部,例如在 中。

The solution that worked for me was putting the <p:commandButton> inside the form or inside where the form data is, say for intance in <p:outputPanel>.

夕色琉璃 2024-08-26 00:49:41
<ui:composition>  
  <h:form id="form1">
    <p:dialog id="dialog1">
      <p:commandButton value="Save" action="#{bean.method1}" /> <!--Working-->
    </p:dialog>
  </h:form>

  <h:form id="form2">
    <p:dialog id="dialog2">
      <p:commandButton value="Save" action="#{bean.method2}" /> <!--Not Working-->
    </p:dialog>
  </h:form>
</ui:composition>

解决;

<ui:composition>  
  <h:form id="form1">
    <p:dialog id="dialog1">
      <p:commandButton value="Save" action="#{bean.method1}" />   <!-- Working  -->
    </p:dialog>

    <p:dialog id="dialog2">
      <p:commandButton value="Save" action="#{bean.method2}" />   <!--Working  -->
    </p:dialog>
  </h:form>
  <h:form id="form2">
    <!-- ..........  -->
  </h:form>
</ui:composition>
<ui:composition>  
  <h:form id="form1">
    <p:dialog id="dialog1">
      <p:commandButton value="Save" action="#{bean.method1}" /> <!--Working-->
    </p:dialog>
  </h:form>

  <h:form id="form2">
    <p:dialog id="dialog2">
      <p:commandButton value="Save" action="#{bean.method2}" /> <!--Not Working-->
    </p:dialog>
  </h:form>
</ui:composition>

To solve;

<ui:composition>  
  <h:form id="form1">
    <p:dialog id="dialog1">
      <p:commandButton value="Save" action="#{bean.method1}" />   <!-- Working  -->
    </p:dialog>

    <p:dialog id="dialog2">
      <p:commandButton value="Save" action="#{bean.method2}" />   <!--Working  -->
    </p:dialog>
  </h:form>
  <h:form id="form2">
    <!-- ..........  -->
  </h:form>
</ui:composition>
同展鸳鸯锦 2024-08-26 00:49:40

简介

每当 UICommand 组件( 等)无法调用关联的操作方法时或 UIInput 组件( 等)无法处理提交的值,并且/或更新模型值,并且您在服务器日志中没有看到任何可搜索的异常和/或警告,当您按照JSF ajax 请求中的异常处理,当您在 web.xml 中设置以下上下文参数时,

<context-param>
    <param-name>jakarta.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

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

可能的原因

  1. UICommandUIInput 组件必须放置在 UIForm 组件内,例如 (因此不是纯 HTML

    ),否则无法将任何内容发送到服务器。 UICommand 组件也不能具有 type="button" 属性,否则它将是一个死按钮,仅对 JavaScript onclick 有用。另请参阅如何发送表单输入值并调用 JSF bean 中的方法不启动回发

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

  3. 不应该发生UIInput值验证/转换错误。您可以使用 显示任何特定于输入的 组件未显示的任何消息。不要忘记在 中包含 id(如果有),这样它也会根据 ajax 请求进行更新。另请参阅 当 p:commandButton 处于按下状态时,h:messages 不显示消息按下

  4. 如果 UICommandUIInput 组件放置在迭代组件内,例如 等,那么您需要确保在表单提交请求的应用请求值阶段保留迭代组件完全相同的。 JSF 将重复它以查找单击的链接/按钮和提交的输入值。将 bean 放入视图范围和/或确保在 bean 的 @PostConstruct 中加载数据模型(因此不在 getter 方法中!)应该可以修复该问题。另请参阅我应该如何以及何时从数据库加载模型对于 JSF 数据表

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

  6. 组件及其所有父组件的 rendered 属性以及任何父组件的 test 属性 /<在表单提交请求的应用请求值阶段,code> 不应计算为 false。 JSF 将重新检查它,作为防止请求被篡改/黑客攻击的一部分。将负责条件的变量存储在 @ViewScoped bean 中,或确保您在 @RequestScoped@PostConstruct 中正确预初始化条件> bean 应该修复它。这同样适用于组件的 disabledreadonly 属性,它们在应用请求值阶段不应评估为 true。另请参阅未调用 JSF CommandButton 操作条件渲染组件中的表单提交未处理h:commandButton 一旦我将其包装在 中就无法工作;强制 JSF无论如何都要处理、验证和更新只读/禁用的输入组件

  7. UICommand 组件的 onclick 属性和 onsubmit UIForm 组件的属性不应返回 false 或导致 JavaScript 错误。在 的情况下,浏览器的 JS 控制台中也应该没有可见的 JS 错误。通常谷歌搜索确切的错误消息已经给你答案了。另请参阅 使用 PrimeFaces 结果手动添加/加载 jQuery在未捕获的类型错误中

  8. 如果您通过 JSF 2.x 或 PrimeFaces 使用 Ajax,请确保您有主模板中的 而不是 。否则,JSF 将无法自动包含包含 Ajax 函数的必要 JavaScript 文件。这将导致浏览器的 JS 控制台中出现 JavaScript 错误,例如“mojarra 未定义”或“PrimeFaces 未定义”。另请参阅 h:commandLink actionlistener 不会在以下情况下调用与 f:ajax 和 ui:repeat 一起使用

  9. 如果您使用 Ajax,并且提交的值最终为 null 或未调用该命令,请确保 UIInputUICommand 感兴趣的组件由 或例如 覆盖,否则它们将不会被执行/已处理。另请参阅提交的表单值未更新添加 时的模型了解 PrimeFaces 流程/更新和JSF f:ajax 执行/渲染属性

  10. 如果提交的值最终仍然为 null,并且您使用 CDI 来管理 Bean,请确保从正确的包中导入作用域注释,否则 CDI 将默认为 < code>@Dependent 它在 EL 表达式的每次计算中有效地重新创建 bean。另请参阅 @SessionScoped bean 失去范围和总是被重新创建,字段变为 nullJSF 2 应用程序中默认的托管 Bean 范围是什么?

  11. 如果 的父级具有 UICommand 按钮预先由来自同一页面中另一个表单的 ajax 请求呈现/更新,那么第一个操作在 JSF 2.2 或更早版本中将始终失败。第二个及后续操作将起作用。这是由视图状态处理中的错误引起的,该错误报告为 JSF 规范问题 790目前已在 JSF 2.3 中修复。对于较旧的 JSF 版本,您需要在 render 中显式指定 的 ID代码>.另请参阅 h:commandButton/h: commandLink 在第一次单击时不起作用,仅在第二次单击时起作用

  12. 如果设置了enctype="multipart/form-data"以支持文件上传,那么您需要确保您至少使用 JSF 2.2,或者负责解析多部分/表单数据请求的 servlet 过滤器已正确配置,否则 FacesServlet 最终将根本无法获取任何请求参数,因此无法应用请求值。如何配置这样的过滤器取决于所使用的文件上传组件。对于 Tomahawk ,请检查此答案,对于 PrimeFaces ,请检查 这个答案。或者,如果您实际上根本没有上传文件,则完全删除该属性。

  13. 确保 actionListenerActionEvent 参数是 jakarta.faces.event.ActionEvent 而不是 java.awt .event.ActionEvent,这是大多数 IDE 建议的第一个自动完成选项。如果您使用 actionListener="#{bean.method}",没有参数也是错误的。如果您不想在方法中使用参数,请使用 actionListener="#{bean.method()}"。或者也许您实际上想使用 action 而不是 actionListener。另请参阅操作和actionListener之间的差异

  14. 确保请求-响应链中没有 PhaseListener 或任何 EventListener 更改了 JSF 生命周期以跳过调用操作阶段,例如通过调用 FacesContext #renderResponse()FacesContext#responseComplete()

  15. 确保同一请求响应链中没有 FilterServlet 以某种方式阻止对 FacesServlet 的请求。例如,登录/安全过滤器,例如 Spring Security。特别是在 ajax 请求中,默认情况下根本不会有任何 UI 反馈。另请参阅 Spring Security 4 和 PrimeFaces 5 AJAX 请求处理.

  16. 如果您使用的是 PrimeFaces ,请确保它们有自己的 < ;h:表单>。因为,这些组件默认由 JavaScript 重新定位到 HTML 的末尾。因此,如果它们最初位于

    中,那么它们现在将不再位于 中。另请参阅 p:commandbutton 操作在 p:dialog 中不起作用

调试提示

如果您仍然卡住,那么就该进行调试了。在客户端,在 Web 浏览器中按 F12 打开 Web 开发人员工具集。单击控制台选项卡即可查看 JavaScript 控制台。它应该没有任何 JavaScript 错误。下面的屏幕截图是来自 Chrome 的示例,它演示了在未声明 的情况下提交启用 的按钮的情况(如上面第 7 点)。

js 控制台

单击网络选项卡可查看 HTTP 流量监视器。提交表单并调查请求标头、表单数据和响应正文是否符合预期。下面的屏幕截图是来自 Chrome 的示例,它演示了使用单个 和单个 成功使用 ajax 提交简单表单的情况

网络监视器

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

在服务器端,确保服务器以调试模式启动。在您希望在处理表单提交期间调用的感兴趣的 JSF 组件的方法中放置一个调试断点。例如,如果是 UICommand 组件,则为 UICommand#queueEvent() 以及 UIInput 组件,那就是 UIInput#validate()。只需逐步执行代码并检查流程和变量是否符合预期。下面的屏幕截图是 Eclipse 调试器的示例。

调试服务器

Introduction

Whenever an UICommand component (<h:commandXxx>, <p:commandXxx>, etc) fails to invoke the associated action method, or an UIInput component (<h:inputXxx>, <p:inputXxxx>, etc) fails to process the submitted values and/or update the model values, and you aren't seeing any googlable exceptions and/or warnings in the server log, also not when you configure an ajax exception handler as per Exception handling in JSF ajax requests, nor when you set below context parameter in web.xml,

<context-param>
    <param-name>jakarta.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

and you are also not seeing any googlable errors and/or warnings in browser's JavaScript console (press F12 in Chrome/Firefox23+/IE9+ to open the web developer toolset and then open the Console tab), then work through below list of possible causes.

Possible causes

  1. UICommand and UIInput components must be placed inside an UIForm component, e.g. <h:form> (and thus not plain HTML <form>), otherwise nothing can be sent to the server. UICommand components must also not have type="button" attribute, otherwise it will be a dead button which is only useful for JavaScript onclick. See also How to send form input values and invoke a method in JSF bean and <h:commandButton> does not initiate a postback.

  2. You cannot nest multiple UIForm components in each other. This is illegal in HTML. The browser behavior is unspecified. Watch out with include files! You can use UIForm components in parallel, but they won't process each other during submit. You should also watch out with "God Form" antipattern; make sure that you don't unintentionally process/validate all other (invisible) inputs in the very same form (e.g. having a hidden dialog with required inputs in the very same form). See also How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?.

  3. No UIInput value validation/conversion error should have occurred. You can use <h:messages> to show any messages which are not shown by any input-specific <h:message> components. Don't forget to include the id of <h:messages> in the <f:ajax render>, if any, so that it will be updated as well on ajax requests. See also h:messages does not display messages when p:commandButton is pressed.

  4. If UICommand or UIInput components are placed inside an iterating component like <h:dataTable>, <ui:repeat>, etc, then you need to ensure that exactly the same value of the iterating component is been preserved during the apply request values phase of the form submit request. JSF will reiterate over it to find the clicked link/button and submitted input values. Putting the bean in the view scope and/or making sure that you load the data model in @PostConstruct of the bean (and thus not in a getter method!) should fix it. See also How and when should I load the model from database for JSF dataTable.

  5. If UICommand or UIInput components are included by a dynamic source such as <ui:include src="#{bean.include}">, then you need to ensure that exactly the same #{bean.include} value is preserved during the view build time of the form submit request. JSF will reexecute it during building the component tree. Putting the bean in the view scope and/or making sure that you load the data model in @PostConstruct of the bean (and thus not in a getter method!) should fix it. See also How to ajax-refresh dynamic include content by navigation menu? (JSF SPA).

  6. The rendered attribute of the component and all of its parents and the test attribute of any parent <c:if>/<c:when> should not evaluate to false during the apply request values phase of the form submit request. JSF will recheck it as part of safeguard against tampered/hacked requests. Storing the variables responsible for the condition in a @ViewScoped bean or making sure that you're properly preinitializing the condition in @PostConstruct of a @RequestScoped bean should fix it. The same applies to the disabled and readonly attributes of the component, which should not evaluate to true during apply request values phase. See also JSF CommandButton action not invoked, Form submit in conditionally rendered component is not processed, h:commandButton is not working once I wrap it in a <h:panelGroup rendered> and Force JSF to process, validate and update readonly/disabled input components anyway

  7. The onclick attribute of the UICommand component and the onsubmit attribute of the UIForm component should not return false or cause a JavaScript error. There should in case of <h:commandLink> or <f:ajax> also be no JS errors visible in the browser's JS console. Usually googling the exact error message will already give you the answer. See also Manually adding / loading jQuery with PrimeFaces results in Uncaught TypeErrors.

  8. If you're using Ajax via JSF 2.x <f:ajax> or e.g. PrimeFaces <p:commandXxx>, make sure that you have a <h:head> in the master template instead of the <head>. Otherwise JSF won't be able to auto-include the necessary JavaScript files which contains the Ajax functions. This would result in a JavaScript error like "mojarra is not defined" or "PrimeFaces is not defined" in browser's JS console. See also h:commandLink actionlistener is not invoked when used with f:ajax and ui:repeat.

  9. If you're using Ajax, and the submitted values end up being null or the command is not invoked, then make sure that the UIInput and UICommand components of interest are covered by the <f:ajax execute> or e.g. <p:commandXxx process>, otherwise they won't be executed/processed. See also Submitted form values not updated in model when adding <f:ajax> to <h:commandButton> and Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes.

  10. If the submitted values still end up being null, and you're using CDI to manage beans, then make sure that you import the scope annotation from the correct package, else CDI will default to @Dependent which effectively recreates the bean on every single evaluation of the EL expression. See also @SessionScoped bean looses scope and gets recreated all the time, fields become null and What is the default Managed Bean Scope in a JSF 2 application?

  11. If a parent of the <h:form> with the UICommand button is beforehand been rendered/updated by an ajax request coming from another form in the same page, then the first action will always fail in JSF 2.2 or older. The second and subsequent actions will work. This is caused by a bug in view state handling which is reported as JSF spec issue 790 and currently fixed in JSF 2.3. For older JSF versions, you need to explicitly specify the ID of the <h:form> in the render of the <f:ajax>. See also h:commandButton/h:commandLink does not work on first click, works only on second click.

  12. If the <h:form> has enctype="multipart/form-data" set in order to support file uploading, then you need to make sure that you're using at least JSF 2.2, or that the servlet filter who is responsible for parsing multipart/form-data requests is properly configured, otherwise the FacesServlet will end up getting no request parameters at all and thus not be able to apply the request values. How to configure such a filter depends on the file upload component being used. For Tomahawk <t:inputFileUpload>, check this answer and for PrimeFaces <p:fileUpload>, check this answer. Or, if you're actually not uploading a file at all, then remove the attribute altogether.

  13. Make sure that the ActionEvent argument of actionListener is an jakarta.faces.event.ActionEvent and thus not java.awt.event.ActionEvent, which is what most IDEs suggest as 1st autocomplete option. Having no argument is wrong as well if you use actionListener="#{bean.method}". If you don't want an argument in your method, use actionListener="#{bean.method()}". Or perhaps you actually want to use action instead of actionListener. See also Differences between action and actionListener.

  14. Make sure that no PhaseListener or any EventListener in the request-response chain has changed the JSF lifecycle to skip the invoke action phase by for example calling FacesContext#renderResponse() or FacesContext#responseComplete().

  15. Make sure that no Filter or Servlet in the same request-response chain has blocked the request fo the FacesServlet somehow. For example, login/security filters such as Spring Security. Particularly in ajax requests that would by default end up with no UI feedback at all. See also Spring Security 4 and PrimeFaces 5 AJAX request handling.

  16. If you are using a PrimeFaces <p:dialog> or a <p:overlayPanel>, then make sure that they have their own <h:form>. Because, these components are by default by JavaScript relocated to end of HTML <body>. So, if they were originally sitting inside a <form>, then they would now not anymore sit in a <form>. See also p:commandbutton action doesn't work inside p:dialog

Debugging hints

In case you still stucks, it's time to debug. In the client side, press F12 in webbrowser to open the web developer toolset. Click the Console tab so see the JavaScript conosle. It should be free of any JavaScript errors. Below screenshot is an example from Chrome which demonstrates the case of submitting an <f:ajax> enabled button while not having <h:head> declared (as described in point 7 above).

js console

Click the Network tab to see the HTTP traffic monitor. Submit the form and investigate if the request headers and form data and the response body are as per expectations. Below screenshot is an example from Chrome which demonstrates a successful ajax submit of a simple form with a single <h:inputText> and a single <h:commandButton> with <f:ajax execute="@form" render="@form">.

network monitor

(warning: when you post screenshots from HTTP request headers like above from a production environment, then make sure you scramble/obfuscate any session cookies in the screenshot to avoid session hijacking attacks!)

In the server side, make sure that server is started in debug mode. Put a debug breakpoint in a method of the JSF component of interest which you expect to be called during processing the form submit. E.g. in case of UICommand component, that would be UICommand#queueEvent() and in case of UIInput component, that would be UIInput#validate(). Just step through the code execution and inspect if the flow and variables are as per expectations. Below screenshot is an example from Eclipse's debugger.

debug server

始于初秋 2024-08-26 00:49:40

如果您的 h:commandLink 位于 h:dataTable 内,则 h:commandLink 可能无法工作还有另一个原因:

底层数据源绑定到 h:dataTable 的它也必须在单击链接时触发的第二个 JSF-Lifecycle 中可用。

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

If your h:commandLink is inside a h:dataTable there is another reason why the h:commandLink might not work:

The underlying data-source which is bound to the h:dataTable must also be available in the second JSF-Lifecycle that is triggered when the link is clicked.

So if the underlying data-source is request scoped, the h:commandLink does not work!

对岸观火 2024-08-26 00:49:40

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

如果您使用 PrimeFaces (或一些类似的 API) p:commandButtonp:commandLink,您可能忘记了将 process="@this" 显式添加到命令组件中。

正如《PrimeFaces 用户指南》第 3.18 节中所述,processupdate 的默认值都是 @form,这与您可能使用的默认值非常相反。期望来自普通 JSF f:ajax 或 RichFaces,它们分别是 execute="@this"render="@none"

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

While my answer isn't 100% applicable, but most search engines find this as the first hit, I decided to post it nontheless:

If you're using PrimeFaces (or some similar API) p:commandButton or p:commandLink, chances are that you have forgotten to explicitly add process="@this" to your command components.

As the PrimeFaces User's Guide states in section 3.18, the defaults for process and update are both @form, which pretty much opposes the defaults you might expect from plain JSF f:ajax or RichFaces, which are execute="@this" and render="@none" respectively.

Just took me a looong time to find out. (... and I think it's rather unclever to use defaults that are different from JSF!)

旧竹 2024-08-26 00:49:40

我想再提一件事,涉及 Primefaces 的 p:commandButton

当您使用 p:commandButton 来执行需要在服务器上完成的操作时,您不能使用 type="button" 因为那是用于 Push按钮,用于执行自定义 javascript,而不会对服务器产生 ajax/非 ajax 请求。

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

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

I would mention one more thing that concerns Primefaces's p:commandButton!

When you use a p:commandButton for the action that needs to be done on the server, you can not use type="button" because that is for Push buttons which are used to execute custom javascript without causing an ajax/non-ajax request to the server.

For this purpose, you can dispense the type attribute (default value is "submit") or you can explicitly use type="submit".

Hope this will help someone!

逆蝶 2024-08-26 00:49:40

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

Got stuck with this issue myself and found one more cause for this problem.
If you don't have setter methods in your backing bean for the properties used in your *.xhtml , then the action is simply not invoked.

花之痕靓丽 2024-08-26 00:49:40

我最近遇到了一个问题,即 UICommand 未在使用 IBM Extended Faces Components 的 JSF 1.2 应用程序中调用。

我在数据表的一行上有一个命令按钮(扩展版本,因此 ),并且 UICommand 不会从表中的某些行触发(不会触发的行)行是否大于默认行显示大小)。

我有一个下拉组件,用于选择要显示的行数。支持该字段的值位于 RequestScope 中。支持表本身的数据位于某种 ViewScope 中(实际上,暂时位于 SessionScope 中)。

如果通过控件增加行显示,该控件的值也绑定到数据表的 rows 属性,则由于此更改而显示的任何行在单击时都不会触发 UICommand。

将此属性放置在与表数据本身相同的范围内可以解决问题。

我认为上面的 BalusC #4 中提到了这一点,但不仅表值需要具有视图或会话范围,而且还需要控制要在该表上显示的行数的属性。

I recently ran into a problem with a UICommand not invoking in a JSF 1.2 application using IBM Extended Faces Components.

I had a command button on a row of a datatable (the extended version, so <hx:datatable>) and the UICommand would not fire from certain rows from the table (the rows that would not fire were the rows greater than the default row display size).

I had a drop-down component for selecting number of rows to display. The value backing this field was in RequestScope. The data backing the table itself was in a sort of ViewScope (in reality, temporarily in SessionScope).

If the row display was increased via the control which value was also bound to the datatable's rows attribute, none of the rows displayed as a result of this change could fire the UICommand when clicked.

Placing this attribute in the same scope as the table data itself fixed the problem.

I think this is alluded to in BalusC #4 above, but not only did the table value need to be View or Session scoped but also the attribute controlling the number of rows to display on that table.

时常饿 2024-08-26 00:49:40

我也遇到了这个问题,只有在打开浏览器的网络控制台后才真正开始研究根本原因。在此之前,我无法收到任何错误消息(即使使用 )。 Web 控制台显示从 返回的 HTTP 405 状态代码。

就我而言,我混合了普通的 HttpServlet(通过 Auth0 提供 OAuth 身份验证)和 JSF Facelets 以及执行应用程序视图和业务逻辑的 bean。

一旦我重构了 web.xml,并删除了中间人 servlet,它就“神奇地”起作用了。

底线是,问题在于中间人 servlet 使用 RequestDispatcher.forward(...) 从 HttpServlet 环境重定向到 JSF 环境,而之前调用的 servlet 使用 HttpServletResponse.sendRedirect(.. .)。

基本上,使用 sendRedirect() 允许 JSF“容器”进行控制,而 RequestDispatcher.forward() 显然不能。

我不知道的是为什么 Facelet 能够访问 bean 属性但无法设置它们,这显然是为了消除 servlet 和 JSF 的混合,但我希望这可以帮助人们避免长时间的头脑风暴。敲桌子。

I had this problem as well and only really started to hone in on the root cause after opening up the browser's web console. Until that, I was unable to get any error messages (even with <p:messages>). The web console showed an HTTP 405 status code coming back from the <h:commandButton type="submit" action="#{myBean.submit}">.

In my case, I have a mix of vanilla HttpServlet's providing OAuth authentication via Auth0 and JSF facelets and beans carrying out my application views and business logic.

Once I refactored my web.xml, and removed a middle-man-servlet, it then "magically" worked.

Bottom line, the problem was that the middle-man-servlet was using RequestDispatcher.forward(...) to redirect from the HttpServlet environment to the JSF environment whereas the servlet being called prior to it was redirecting with HttpServletResponse.sendRedirect(...).

Basically, using sendRedirect() allowed the JSF "container" to take control whereas RequestDispatcher.forward() was obviously not.

What I don't know is why the facelet was able to access the bean properties but could not set them, and this clearly screams for doing away with the mix of servlets and JSF, but I hope this helps someone avoid many hours of head-to-table-banging.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文