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

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

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

考えられる原因と解決策は何でしょうか?

ベストアンサー1

導入

UICommandコンポーネント(<h:commandXxx><p:commandXxx>など)が関連するアクションメソッドの呼び出しに失敗した場合、またはUIInputコンポーネント(<h:inputXxx><p:inputXxxx>など)が送信された値の処理やモデル値の更新に失敗した場合、サーバーログにグーグル検索可能な例外や警告が表示されず、Ajax例外ハンドラを次のように構成した場合も同様です。JSF ajax リクエストにおける例外処理、また、以下のコンテキストパラメータを設定する場合web.xml

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

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

考えられる原因

  1. UICommandまた、コンポーネントはコンポーネントUIInput内に配置する必要があります(つまり、プレーン HTML ではありません)。そうしないと、サーバーに何も送信されません。コンポーネントには属性も設定できません。そうしないと、JavaScript でのみ有効なデッドボタンになります。UIForm<h:form><form>UICommandtype="button"onclickフォーム入力値を送信し、JSF Bean でメソッドを呼び出す方法そして<h:commandButton> はポストバックを開始しません

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

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

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

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

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

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

  8. <f:ajax>JSF 2.xまたは PrimeFaces経由で Ajax を使用している場合は、マスター テンプレートに ではなく が<p:commandXxx>あることを確認してください。そうしないと、JSF は Ajax 関数を含む必要な JavaScript ファイルを自動的に含めることができません。その結果、ブラウザの JS コンソールに「mojarra が定義されていません」または「PrimeFaces が定義されていません」などの JavaScript エラーが表示されます。<h:head><head>h:commandLink アクションリスナーは、f:ajax および ui:repeat と併用すると呼び出されません。

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

  10. 送信された値が依然として になりnull、CDI を使用して Bean を管理している場合は、正しいパッケージからスコープ注釈をインポートしていることを確認してください。そうしないと、CDI はデフォルトで になり、@DependentEL 式の評価ごとに Bean が効果的に再作成されます。@SessionScoped Bean はスコープを失い、常に再作成され、フィールドが null になります。そしてJSF 2 アプリケーションのデフォルトのマネージド Bean スコープとは何ですか?

  11. <h:form>ボタンの親が、UICommand同じページ内の別のフォームからのAjaxリクエストによって事前にレンダリング/更新されている場合、JSF 2.2以前では最初のアクションは常に失敗します。2番目以降のアクションは機能します。これは、次のように報告されているビューステート処理のバグによって発生します。JSF 仕様の問題 790これは現在 JSF 2.3 で修正されています。古い JSF バージョンでは、の で<h:form>のID を明示的に指定する必要があります。render<f:ajax>h:commandButton/h:commandLink は最初のクリックでは機能せず、2 回目のクリックでのみ機能します。

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

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

  14. 要求応答チェーン内のPhaseListenerいずれの も、またはを呼び出すなどして、JSF ライフサイクルを変更して呼び出しアクション フェーズをスキップしていないことを確認します。EventListenerFacesContext#renderResponse()FacesContext#responseComplete()

  15. 同じリクエスト レスポンス チェーン内のFilterまたは が何らかの方法でリクエストをブロックしていないことを確認します。たとえば、Spring Security などのログイン/セキュリティ フィルターなどです。特に、デフォルトでは UI フィードバックがまったく行われない Ajax リクエストではそうです。ServletFacesServletSpring Security 4 と PrimeFaces 5 の AJAX リクエスト処理

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

デバッグのヒント

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

js コンソール

[ネットワーク]タブをクリックして、HTTP トラフィック モニターを表示します。フォームを送信し、リクエスト ヘッダーとフォーム データ、および応答本文が期待どおりであるかどうかを調べます。以下のスクリーンショットは、1 つの<h:inputText>と 1 つの<h:commandButton>を含む単純なフォームの Ajax 送信が成功したことを示す Chrome の例です<f:ajax execute="@form" render="@form">

ネットワークモニター

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

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

デバッグサーバー

おすすめ記事