现在的位置: 首页 > 综合 > 正文

h:commandLink / h:commandButton 不被执行的原因

2013年09月01日 ⁄ 综合 ⁄ 共 2973字 ⁄ 字号 评论关闭

stackoverflow上找到的一篇问答,非常详尽的罗列了可能的各种情况,我就遇到了其中的第7点,相信做jsf开发的朋友都会遇到这类问题。

h:commandLink / h:commandButton is not being invoked

Whenever an UICommand component fails to invoke the associated action method or an
UIInput element fails to update the model value, then verify the following:

  1. UICommand and UIInput components must be placed inside an
    UIForm component, e.g. <h:form>.

  2. You cannot nest multiple UIForm components in each other. This is namely illegal in HTML. Watch out with include files!

  3. No UIInput value validation/conversion error should have been 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.

  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 component is been preserved during the apply request values phase of the form submit request. JSF will namely 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 (post)constructor of the bean (and thus not in the getter method!) should fix it.

  5. The rendered attribute of the component and all of the parent components should not evaluate to
    false during the apply request values phase of the form submit request. JSF will namely recheck it then as part of safeguard against tampered/hacked requests. Putting the bean in the view scope and/or making sure that you're preinitializing the
    condition in (post)constructor of the bean should fix it. The same applies to the
    disabled attribute of the component, which should not evaluate to
    true
    during processing the form submit.

  6. If you're using JSF 2.x <f:ajax> on the command component, 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
    jsf.js JavaScript file which contains the Ajax functions. This would result in a JavaScript error like "mojarra is not defined" in the browser's builtin JavaScript console.

  7. If a parent of the <h:form> with the
    UICommand button is been rendered/updated by an ajax request beforehand, then the first action will always fail. 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 fixed in JSF 2.2. For JSF 2.0 and 2.1 you need to explicitly specify the ID of the
    <h:form> in the render of the <f:ajax>.

  8. Be sure that the ActionEvent argument of
    actionListener is an javax.faces.event.ActionEvent and thus not
    java.awt.event.ActionEvent, which is what most IDEs suggest as 1st autocomplete option.

  9. Be 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().

  10. Be sure that no Filter or Servlet in the same request-response chain has blocked the request fo the
    FacesServlet somehow.

My bet that your particular problem is caused by point 2:
nested forms. You probably already have a <h:form> in the parent page which wraps the include file. The include file itself should
not have a <h:form>. You can also fix it the other way round, ensure that the parent page does
not have a <h:form> around the place of the include file.

【上篇】
【下篇】

抱歉!评论已关闭.