359

<h:commandLink><h:commandButton>またはを使用しているときに、タグに関連付けられ<f:ajax>actionactionListenerまたはメソッドが呼び出されないことがあります。listenerまたは、Bean プロパティが送信されたUIInput値で更新されません。

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

4

12 に答える 12

707

序章

コンポーネントUICommand( <h:commandXxx><p:commandXxx>など) が関連付けられたアクション メソッドの呼び出しに失敗するか、UIInputコンポーネント ( <h:inputXxx><p:inputXxxx>など) が送信された値の処理やモデル値の更新に失敗し、Google で認識できる例外やまた、JSF ajax requests での例外処理に従って 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内に配置する必要があります。コンポーネントも属性を持ってはなりません。そうしないと、JavaScript でのみ役立つデッド ボタンになります。フォーム入力値を送信して JSF Beanでメソッドを呼び出す方法も参照してください。 <h:commandButton> はポストバックを開始しませんUIForm<h:form><form>UICommandtype="button"onclick

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

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

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

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

  6. renderedコンポーネントとそのすべての親の属性、およびtest任意の親<c:if>/の属性は、フォーム送信リクエストのリクエスト値の適用フェーズで<c:when>評価されるべきではありません。falseJSF は、改ざん/ハッキングされたリクエストに対する保護の一環として、再チェックします。条件の原因となる変数を Bean に格納するか、Bean@ViewScopedの条件を適切に事前に初期化していることを確認すると、問題が修正されます。コンポーネントのおよび属性にも同じことが適用されます。これらは、リクエスト値の適用フェーズで評価されるべきではありません。JSF CommandButton アクションが呼び出されない、条件付きでレンダリングされたコンポーネントでのフォーム送信が処理されない、も参照してください。@PostConstruct@RequestScopeddisabledreadonlytrueh:commandButton が <h:panelGroup render> でラップすると機能しなくなり、 JSF に読み取り専用/無効な入力コンポーネントの処理、検証、更新を強制する

  7. コンポーネントのonclick属性とUICommandコンポーネントのonsubmit属性は、JavaScript エラーUIFormを返しfalseたり、引き起こしたりしてはなりません。ブラウザの JS コンソールに JS エラーが表示される<h:commandLink>か、表示されない場合があります。<f:ajax>通常、正確なエラー メッセージをグーグル検索すると、すでに答えが得られます。PrimeFaces で jQuery を手動で追加/ロードすると Uncaught TypeErrors が発生するも参照してください。

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

  9. Ajax を使用していて、送信された値が最終的に である場合は、対象のおよびコンポーネントがor egでカバーされ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 で修正されているビュー ステート処理のバグが原因です。<h:form>古い JSF バージョンの場合、 のでrenderのID を明示的に指定する必要があります<f:ajax>h:commandButton/h:commandLink は最初のクリックでは機能せず、2 回目のクリックでのみ機能するも参照してください。

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

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

  14. リクエスト/レスポンス チェーンのnoPhaseListenerまたは anyEventListenerが JSF ライフサイクルを変更して、たとえばFacesContext#renderResponse()orを呼び出してアクション呼び出しフェーズをスキップしたことを確認しますFacesContext#responseComplete()

  15. Filterなんらかの理由でリクエストをブロックしていない、またはServlet同じリクエスト - レスポンス チェーン内にあることを確認してくださいFacesServlet。たとえば、Spring Security などのログイン/セキュリティ フィルター。特に、デフォルトでは UI フィードバックがまったくない ajax リクエストでは。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 エラーがないようにする必要があります。以下のスクリーンショットは Chrome の例で、<f:ajax>有効なボタンを宣言せずに送信した場合を示しています<h:head>(上記のポイント 7 で説明したように)。

js コンソール

[ネットワーク] タブをクリックして、HTTP トラフィック モニターを表示します。フォームを送信し、リクエスト ヘッダーとフォーム データ、およびレスポンス ボディが期待どおりかどうかを調査します。以下のスクリーンショットは Chrome の例で、単一の単純なフォームと<h:inputText>単一<h:commandButton><f:ajax execute="@form" render="@form">.

ネットワークモニター

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

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

デバッグ サーバー

于 2010-01-22T20:13:22.793 に答える
55

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

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

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

于 2010-11-08T22:25:06.073 に答える
30

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

PrimeFaces (または類似の API)p:commandButtonまたはを使用している場合、コマンド コンポーネントp:commandLinkに明示的に追加するのを忘れている可能性があります。process="@this"

PrimeFaces User's Guide のセクション 3.18 で述べられているように、 と のデフォルトprocessupdatebothであり、プレーンな JSFまたは RichFaces に@form期待されるデフォルト (それぞれとである) とはかなり対照的です。f:ajaxexecute="@this"render="@none"

調べるのに長い時間がかかりました。(...そして、JSFとは異なるデフォルトを使用するのはかなり不謹慎だと思います!)

于 2013-01-03T18:51:03.647 に答える
3

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

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

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

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

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

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

于 2015-10-13T18:23:29.220 に答える
3

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

于 2013-02-23T10:55:59.083 に答える
2

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

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

web.xml をリファクタリングし、仲介者サーブレットを削除すると、「魔法のように」機能しました。

要するに、仲介者サーブレットが RequestDispatcher.forward(...) を使用して HttpServlet 環境から JSF 環境にリダイレクトしていたのに対し、それ以前に呼び出されていたサーブレットは HttpServletResponse.sendRedirect(.. .)。

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

わからないのは、なぜ facelet が Bean のプロパティにアクセスできたのに、それらを設定できなかったのかということです。これは、サーブレットと JSF の混合を廃止することを明らかに叫んでいますが、これが誰かが何時間も頭を悩ませるのを避けるのに役立つことを願っています-テーブルバンギング。

于 2017-04-11T16:11:51.717 に答える