commandButton / commandLink / ajaxアクション/リスナーメソッドが呼び出されていないか、入力値が設定/更新されていません


345

時々 、使用時<h:commandLink><h:commandButton>または<f:ajax>actionactionListenerまたはlistenerタグに関連付けられた方法は、単に起動されていません。または、送信されたUIInput値でBeanプロパティが更新されません。

これの考えられる原因と解決策は何ですか?

回答:


687

前書き

たびUICommand成分(<h:commandXxx><p:commandXxx>など)に関連するアクションメソッド、または起動に失敗したUIInputコンポーネントを(<h:inputXxx><p:inputXxxx>など)提出された値を処理および/またはモデル値の更新に失敗し、あなたはどんなgooglable例外が表示されない、および/またはサーバーログの警告、JSF ajaxリクエストの例外処理に従ってajax例外ハンドラーを構成した場合、以下のコンテキストパラメーターを設定した場合もweb.xml

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

また、ブラウザーのJavaScriptコンソールにグーグルエラーや警告が表示されない(Chrome / Firefox23 + / IE9 +でF12を押してWeb開発者ツールセットを開き、[ コンソール ]タブを開く)場合は、以下の考えられる原因のリストに進んでください。

考えられる原因

  1. UICommandおよびUIInput部品の内側に配置する必要がありますUIForm例えば、コンポーネント<h:form>(プレーンHTMLをひいてはいない<form>)、それ以外は何もサーバーに送信することはできません。UICommandコンポーネントもtype="button"属性を持っていてはなりません。そうでなければ、それはJavaScriptにのみ役立つデッドボタンになりますonclick。参照してフォームの入力値を送信する方法とJSF Bean内のメソッドを呼び出す<H:コマンドボタンを>ポストバックを開始しません

  2. 複数のUIFormコンポーネントを互いにネストすることはできません。これはHTMLでは違法です。ブラウザの動作は規定されていません。インクルードファイルに注意してください!UIFormコンポーネントを並行して使用できますが、送信中にコンポーネントが互いに処理することはありません。また、 "God Form"アンチパターンにも注意する必要があります。非常に同じフォームにある他のすべての(非表示)入力を誤って処理/検証しないようにしてください(たとえば、非常に同じフォームに必要な入力がある非表示ダイアログがある)。JSFページで<h:form>を使用する方法も参照してください。シングルフォーム?複数のフォーム?ネストされたフォーム?

  3. UIInput値の検証/変換エラーは発生しません。を使用<h:messages>して、入力固有の<h:message>コンポーネントでは表示されないメッセージを表示できます。含めることを忘れてはいけないidのを<h:messages>して<f:ajax render>、もしあれば、それは、AJAX要求にうまくとして更新されること。p:commandButtonが押されたときにh:messagesがメッセージを表示しないことも参照してください。

  4. 場合UICommandUIInput部品には同じ反復処理コンポーネントの内側に配置されている<h:dataTable><ui:repeat>など、あなたがまったく同じことを確認する必要がありvalue反復処理コンポーネントの中に保存されているフォームの要求値適用フェーズは、リクエストを送信してください。JSFはそれを繰り返して、クリックされたリンク/ボタンと送信された入力値を見つけます。Beanをビュースコープに配置するか@PostConstruct、Beanにデータモデルをロードするようにして(したがってゲッターメソッドではなく!)、それを修正する必要があります。h:dataTableのデータベースからモデルをロードする方法とタイミングも参照してください。

  5. 場合UICommandUIInputコンポーネントがのようなダイナミックなソースによって含まれている<ui:include src="#{bean.include}">、あなたは正確に同じことを確認する必要があります#{bean.include}フォームのビュービルド時にリクエストを送信した値が保存されます。JSFは、コンポーネントツリーの構築中に再実行します。Beanをビュースコープに配置するか@PostConstruct、Beanにデータモデルをロードするようにして(したがってゲッターメソッドではなく!)、それを修正する必要があります。ナビゲーションメニューで動的インクルードコンテンツをajax-refreshする方法も参照してください(JSF SPA)

  6. renderedコンポーネントとその親のすべての属性とtest任意の親の属性は、<c:if>/ <c:when>に評価されてはならないfalseフォーム要求を提出の要求値の適用フェーズ中に。JSFは、改ざん/ハッキングされた要求に対する保護の一環として再チェックします。条件の原因となる変数を@ViewScopedBeanに格納するか、Beanの条件を適切に事前初期化していることを確認する@PostConstructと、@RequestScoped問題が修正されます。同じことがdisabledコンポーネントの属性にもtrue当てはまり、リクエスト値の適用フェーズでは評価されません。参照してくださいJSFのCommandButtonアクションが呼び出されないフォームが処理されない条件付きでレンダリングされたコンポーネントに提出し、h:commandButtonは、<h:panelGroup Rendered>でラップすると機能しなくなります

  7. コンポーネントのonclick属性とUICommandコンポーネントのonsubmit属性がJavaScriptエラーをUIForm返しfalseたり、引き起こしたりしてはなりません。ブラウザのJSコンソールにJSエラーが表示されるか、表示されないようにする<h:commandLink>必要が<f:ajax>あります。通常、正確なエラーメッセージをグーグルすることで、すでに回答が得られます。参照してください。キャッチされないTypeErrorsでPrimeFacesの結果と手動で追加/負荷のjQueryを

  8. JSF 2.x <f:ajax>またはPrimeFaces <p:commandXxx>などを介してAjaxを使用している場合は<h:head>、マスターテンプレートにの代わりにがあることを確認してください<head>。そうしないと、JSFはAjax関数を含む必要なJavaScriptファイルを自動インクルードできません。これにより、ブラウザのJSコンソールで「mojarra is not defined」や「PrimeFaces is not defined」などのJavaScriptエラーが発生します。f:ajaxおよびui:repeatと一緒に使用するとh:commandLink actionlistenerが呼び出されないも参照してください。

  9. Ajaxを使用していて、送信された値がになる場合は、対象のおよびコンポーネントがまたはでカバーされてnullいることを確認してください。そうでない場合、それらは実行/処理されません。<f:ajax>を<h:commandButton>に追加するときにモデルで更新されない送信済みフォームの値およびPrimeFacesプロセス/更新とJSF f:ajax実行/レンダリング属性についても参照してください。UIInputUICommand<f:ajax execute><p:commandXxx process>

  10. 送信された値が依然としてでありnull、CDIを使用してBeanを管理している場合は、正しいパッケージからスコープアノテーションをインポートしてください。そうでない場合、CDIはデフォルト@Dependentで、ELのすべての単一評価でBeanを効果的に再作成します式。@SessionScoped Beanスコープを失い、常に再作成され、フィールドはnullになり、JSF 2アプリケーションのデフォルトの管理対象Beanスコープは何ですか?も参照してください

  11. 親ならば<h:form>UICommand、ボタンが事前にレンダリングされている/同一ページ内の別のフォームから来るのAjaxリクエストによって更新され、その後、最初のアクションは常にJSF 2.2またはそれ以上の年齢で失敗します。2番目以降のアクションは機能します。これは、JSF仕様の問題790として報告され、現在JSF 2.3で修正されているビューステート処理のバグが原因です。古いJSFのバージョンでは、明示的にIDを指定する必要が<h:form>render<f:ajax>。参照してください時間:commandButtonの/ hは:のcommandLinkは、最初のクリックで動作しない、唯一の第二のクリックで動作します

  12. 場合<h:form>しているenctype="multipart/form-data"サポートファイルのアップロードするために設定され、その後、あなたは、そうでない場合は、少なくともJSF 2.2を使用して、またはマルチパート/フォームデータ要求を解析するための責任があるサーブレットフィルタが正しく設定されていることをしていることを確認する必要がありFacesServlet意志をリクエストパラメータをまったく取得しないため、リクエスト値を適用できません。このようなフィルターの構成方法は、使用されているファイルアップロードコンポーネントによって異なります。トマホークの<t:inputFileUpload>場合はこの回答を確認し、PrimeFacesの<p:fileUpload>場合はこの回答を確認してください。または、実際にファイルをまったくアップロードしない場合は、属性を完全に削除します。

  13. ほとんどのIDEが最初のオートコンプリートオプションとして提案しているように、のActionEvent引数がactionListenerである ことを確認してください。を使用する場合も、引数がないことは間違いです。メソッドに引数が必要ない場合は、を使用してください。または、実際にの代わりに使用したい場合もあります。actionとactionListenerの違いも参照してください。javax.faces.event.ActionEventjava.awt.event.ActionEventactionListener="#{bean.method}"actionListener="#{bean.method()}"actionactionListener

  14. たとえばやを呼び出して、アクションの呼び出しフェーズをスキップするPhaseListenerようEventListenerに、リクエスト/レスポンスチェーンの何も変更されていないことを確認してください。FacesContext#renderResponse()FacesContext#responseComplete()

  15. なんらかの理由で要求がブロックされていないFilterServlet、同じ要求応答チェーン内にあることを確認してくださいFacesServlet。たとえば、Spring Securityなどのログイン/セキュリティフィルター。特にajaxリクエストでは、デフォルトではUIフィードバックがまったくありません。Spring Security 4およびPrimeFaces 5のAJAXリクエスト処理も参照してください。

  16. PrimeFaces <p:dialog>またはを使用<p:overlayPanel>している場合は、それらが独自のものを持っていることを確認してください<h:form>。なぜなら、これらのコンポーネントはデフォルトでJavaScriptによってHTMLの最後に再配置されるから<body>です。したがって、元々はの中に座っていた<form>場合は、もはやに座っていません<form>p:commandbuttonアクションがp:dialog内で機能しないも参照してください

  17. フレームワークのバグ。たとえば、RichFacesには、属性(または、場合によってはサブ要素)を持つUI要素を使用すると、「変換エラー」が発生します。このバグにより、カレンダーの日付に値が設定されていない場合にBeanメソッドが呼び出されなくなります。フレームワークのバグの追跡は、簡単な作業例から始めて、バグが見つかるまでページを作成し直すことで実現できます。rich:calendardefaultLabelrich:placeholder

デバッグのヒント

それでも行き詰まっている場合は、デバッグの時間です。クライアント側で、WebブラウザーでF12キーを押して、Web開発者ツールセットを開きます。[ コンソール ]タブをクリックして、JavaScript コンソールを表示します。JavaScriptエラーがあってはなりません。以下のスクリーンショットは、宣言されて<f:ajax>いない<h:head>(上記のポイント7で説明されている)間に有効なボタンを送信するケースを示すChromeの例です。

jsコンソール

[ ネットワーク ]タブをクリックして、HTTPトラフィックモニターを表示します。フォームを送信し、リクエストヘッダーとフォームデータ、および応答本文が期待どおりかどうかを調査します。スクリーンショットの下には成功したアヤックスは、単一でシンプルなフォームの提出を示してChromeからの例で<h:inputText>、シングル<h:commandButton><f:ajax execute="@form" render="@form">

ネットワークモニター

(警告:上記のようなHTTPリクエストヘッダーのスクリーンショットを本番環境から投稿する場合は、スクリーンショットのセッションCookieをスクランブル/難読化して、セッションハイジャック攻撃を回避してください!)

サーバー側で、サーバーがデバッグモードで起動されていることを確認します。フォーム送信の処理中に呼び出されると予想される対象のJSFコンポーネントのメソッドにデバッグブレークポイントを配置します。たとえば、UICommandコンポーネントの場合はそれがUICommand#queueEvent()UIInputコンポーネントの場合はになりますUIInput#validate()。コード実行をステップ実行し、フローと変数が期待どおりかどうかを調べます。以下のスクリーンショットは、Eclipseのデバッガーの例です。

デバッグサーバー


1
あなたの2点目は私に考えさせました-長い間。メインファイルのf:viewタグがほとんどの問題の原因であることがわかりました。そして、それはフォームをレンダリングするためでしょうか?
Paulo Guedes、

2
@pauloguedes f:viewがフォームをレンダリングすることを示すものは何も見つかりません。私の理解では、それは単なるコンテナであるということです。私の経験では、f:viewは要素をレンダリングしません。
ルーカス

@baluscポイント4について少し説明します。commandLinkがdataTable自体にない場合でも、問題はありますか?
ルーカス

おかげで、ポイントはポイントです:Beanをビュースコープに配置するか、Beanの(ポスト)コンストラクターにデータモデルを確実にロードしてください(したがって、getterメソッドではありません!)
merveotesi 2013

2
@Kukeltje:EL例外がスローされます(回答の最初の段落で既にカバーされています)
BalusC

54

あなたh:commandLinkが中にいる場合、h:dataTableそれが機能しh:commandLinkない可能性がある別の理由があります:

にバインドされている基礎となるデータソースはh:dataTable、リンクがクリックされたときにトリガーされる2番目のJSF-Lifecycleでも使用できる必要があります。

したがって、基になるデータソースがリクエストスコープの場合、h:commandLink機能しません。


2
わかりました、それは私には完全に明確ではありませんでした。私の場合は少なくともUICommand / UIDataを明示的に扱っていなかったので、私の回答がとにかく役に立てば幸いです。「解決策」は、バッキングBeanをリクエストスコープからセッションスコープに
プロモートしていた

1
私はJensのコメントを2つ目に... RequestScoped BeanをSessionScopedに設定すると、私のdataTableに違いが生じました-ありがとう
Zack

28

私の回答は100%当てはまるわけではありませんが、ほとんどの検索エンジンはこれを最初のヒットとして見つけましたが、それでも投稿することにしました。

PrimeFaces(または同様のAPI)を使用している場合p:commandButtonまたはp:commandLink、チャンスはあなたが明示的に追加することを忘れているということであるprocess="@this"コマンド・コンポーネントに。

『PrimeFaces User's Guide』のセクション3.18に記載されているように、processおよびのupdate両方@formのデフォルトは、プレーンJSF f:ajaxまたはRichFacesに期待されるデフォルトであるexecute="@this"およびにrender="@none"それぞれ反対しています。

調べるのに時間がかかった。(...そしてJSFとは異なるデフォルトを使用することはかなり賢くないと思います!)


6
PrimeFacesのデフォルトprocess@formです。したがって、アクションがこのように呼び出されないが、を使用するときに呼び出される場合、@thisおそらく私の答えのポイント3が適用されます。
BalusC 2013年

3
これはできません。私が持っていたp:commandButton私が追加されるまでのactionListenerメソッド呼び出しませんでしたがprocess="@this"。さらに、PrimeFacesユーザーガイドには、セクション3.18と3.19で述べたデフォルトが明示されています。それはここにあります:primefaces.googlecode.com/files/primefaces_users_guide_3_4.pdf ...多分デフォルトは変更されましたか?
Kawu

8
ドキュメントのエラーの可能性があります。削除process="@this"して追加<p:messages autoUpdate="true">(またはキューに入れられているが表示されていないメッセージのサーバーログを読み取るだけ)を行うと、実際に変換/検証エラーが発生していることがわかります。
BalusC 2013年

なぜあなたはこの質問を削除しなかったstackoverflow.com/questions/60673695/...
Kukeltje

今はあまり価値がないかもしれないと思いました...元に戻しました。
カウ

9

Primefacesに関係するもう1つのことを述べp:commandButtonます。

p:commandButtonサーバーで実行する必要のあるアクションにを使用すると、サーバーへのajax / non-ajaxリクエストを引き起こさずにカスタムJavaScriptを実行するために使用されるプッシュボタン用であるtype="button"ため、使用できません。

この目的のために、type属性をディスペンスする"submit"か(デフォルト値は)、明示的にを使用できますtype="submit"

これが誰かを助けることを願っています!


これは私たちのページの1つにある私の主な問題でした。受け入れられた回答のどのポイントも私たちを近づけませんでした。どこでこの情報を見つけましたか?
Uriel Arvizu、2015年

ええと、私はその問題を何度もp:commandButton経験しましたが、調査したところ、いくつかのtype属性値があり、buttonクライアント側のすべてに関係するものでした。それはでこれを見つけることが少し難しいPrimefacesのdocが、ここで一つのリンクは次のとおりです。developer.am/primefaces/...
akelec

あなたの提出のヒントは、私が数日間直面してきた私の問題を解決しました。投稿ありがとうございました!
gpuk360 2017年

ありがとう、それは私の喜びです。私たちの多くはそのような問題を抱えていたので、私は故意にこの答えを出しました。私は何が何であるかを理解するまで数日も失っていました。
akelec

3

私自身、この問題に悩まされ、この問題の原因をもう1つ見つけました。* .xhtmlで使用されるプロパティのバッキングBeanにセッターメソッドがない場合、アクションは呼び出されません。


5
それはむしろ自己説明的なものになるはずPropertyNotWritableExceptionです。表示されない場合は、適切なajax例外ハンドラーなしでajaxリクエストを発行した可能性がありますが、サーバーログに表示されるはずです。
BalusC 2013

3
p:commandButtonのajax = "false"を作成するまで、その例外は表示されませんでした。
Dnavir 2013


3

最近、IBM Extended Faces Componentsを使用するJSF 1.2アプリケーションでUICommandが呼び出されないという問題に遭遇しました。

データテーブルの行にコマンドボタンがありました(拡張バージョンなので、 <hx:datatable>)、UICommandはテーブルの特定の行からは起動しませんでした(起動しない行は、デフォルトの行表示サイズより大きい行でした)。

表示する行数を選択するためのドロップダウンコンポーネントがありました。このフィールドを裏付ける値はにありましたRequestScope。テーブル自体を支えるデータは、一種のViewScope(実際には、一時的にSessionScope)でした。

どの値もデータテーブルのrows属性にバインドされているコントロールを介して行の表示が増加した場合、この変更の結果として表示された行がクリックされたときにUICommandを起動できませんでした。

この属性をテーブルデータ自体と同じスコープに配置すると、問題が解決しました。

これは上記のBalusC#4で暗示されていると思いますが、テーブル値をビューまたはセッションスコープにする必要があるだけでなく、そのテーブルに表示する行数を制御する属性も必要でした。


2

私もこの問題を抱えていて、ブラウザーのWebコンソールを開いてから、根本的な原因を突き止めるようになりました。それまでは、エラーメッセージを受け取ることができませんでした(を使用しても<p:messages>)。Webコンソールに、から返されるHTTP 405ステータスコードが表示されました<h:commandButton type="submit" action="#{myBean.submit}">

私の場合、Auth0を介してOAuth認証を提供するバニラHttpServletと、アプリケーションビューとビジネスロジックを実行するJSFファセットとBeanが混在しています。

web.xmlをリファクタリングし、middle-man-servletを削除すると、「魔法のように」機能しました。

結論として、問題は、middle-man-servletがRequestDispatcher.forward(...)を使用してHttpServlet環境からJSF環境にリダイレクトするのに対して、サーブレットがHttpServletResponse.sendRedirect(..でリダイレクトされる前に呼び出されていたことです。 。)。

基本的に、sendRedirect()を使用すると、JSFの「コンテナー」が制御を取得できましたが、RequestDispatcher.forward()は明らかにそうではありませんでした。

私が知らないのは、faceletがBeanのプロパティにアクセスできたが設定できなかった理由です。これは、サーブレットとJSFの混合を排除することで明らかに悲鳴を上げていますが、これが誰かが何時間もヘッドを回避するのに役立つことを願っていますto-table-banging。


1

<h:commandLink>のアクションの実行がrichfaces datatable拒否された問題をデバッグするのはとても楽しいものでした。テーブルはある時点で機能していましたが、明確な理由もなく停止しました。リッチフェイスrich:datatablerowKeyConverter行キーとしてうまく使用されているnullを返す間違った方法を使用していたことを確認するためだけに、私は石を裏返さずに放置しませんでした。これにより、私の<h:commandLink>アクションが呼び出されなくなりました。


0

もう1つの可能性:最初の呼び出しは機能するがその後の呼び出しは機能しないという症状である場合、PrimeFaces 3.xをJSF 2.2で使用している可能性があります


-1

配置に関する問題を修正しました:

<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>

これは、600を超える投票の回答で第1位です。別の答えとして書く必要はありません。
Kukeltje

-1

これは私のために働いている解決策です。

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

ここでは、Ajax呼び出しにはprocess = "userGroupSetupForm"属性が必須です。actionListenerが@ViewScope Beanからメソッドを呼び出しています。グロウルメッセージ、Datatable:userGroupListおよびForm:userGroupSetupFormも更新します。


-2
<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>

申し訳ありませんが、これは私の控えめな意見では全く真実ではありません。2つのダイアログが機能するには独自の形式である必要があることを効果的に述べます。99%の確実性であなたが解決した別の問題があり、今それが解決策であると考えています...
Kukeltje

これは含まれているページです。おそらく、これが問題を引き起こす可能性があります。投票する前にテストする必要があります。
KenanGökbak19年

いいえ、投稿する前に最小限の再現可能な例を作成する必要がありました (そして、私がテストできるのはそれだけです)...そして、はいインクルードはダイアログとフォームで問題を引き起こす可能性がありますが、それでも問題はここで解決したくないようです。最初の例は完全に問題なく、2番目の例は100%の確実性で、存在しない問題の解決策ではありません
Kukeltje

とにかく。私のアプリケーションは正常に動作しています。ダイアログボックスがフォームのどこにあるかは重要ではないと思います。別の問題を解決するには、2つ目のフォームを作成する必要があります。
KenanGökbak19年

アプリケーションは動作している可能性がありますが、それは元の問題と「解決策」からは明らかではありません。さらに、「フォームのダイアログボックスがどこにあるかは重要ではないと思います。私の発言を支持する矛盾。申し訳ありませんが、あなたの答えは明らかに間違っています...(すでに別の反対投票があります)
Kukeltje
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.