commandButton/commandLink/ajax アクション/リスナー メソッドが呼び出されない、または入力値が設定/更新されない
-
22-09-2019 - |
質問
時々、使用するときに、 <h:commandLink>
, <h:commandButton>
または <f:ajax>
, 、 action
, actionListener
または listener
タグに関連付けられたメソッドが呼び出されないだけです。または、Bean プロパティが送信時に更新されません。 UIInput
価値観。
これについて考えられる原因と解決策は何ですか?
解決
導入
いつでも UICommand
成分 (<h:commandXxx>
, <p:commandXxx>
, 、など)、関連付けられたアクション メソッドの呼び出しに失敗するか、 UIInput
成分 (<h:inputXxx>
, <p:inputXxxx>
, 、など)送信された値の処理やモデル値の更新に失敗し、Google で検索できる例外や警告がサーバー ログに表示されず、また、次のように ajax 例外ハンドラーを設定した場合にも表示されません。 JSF Ajaxリクエストでの例外処理, 、または以下の context パラメータを設定した場合でも、 web.xml
,
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
また、ブラウザの JavaScript コンソールにも、Google で検索できるエラーや警告が表示されません (Chrome/Firefox23+/IE9+ で F12 を押して Web 開発者ツールセットを開き、 コンソール タブ)、次に考えられる原因の以下のリストを確認してください。
考えられる原因
UICommand
そしてUIInput
コンポーネントは内部に配置する必要がありますUIForm
コンポーネント、例:<h:form>
(したがって、プレーンな HTML ではありません)<form>
)、そうでない場合はサーバーに何も送信できません。UICommand
コンポーネントにも次のものがあってはなりませんtype="button"
属性を指定しないと、JavaScript でのみ役立つ無効なボタンになります。onclick
. 。こちらも参照 フォーム入力値を送信し、JSF Bean のメソッドを呼び出す方法 そして <h:commandButton> はポストバックを開始しません.複数をネストすることはできません
UIForm
お互いのコンポーネント。これは HTML では違法です。ブラウザの動作は未指定です。インクルードファイルには注意してください!使用できますUIForm
コンポーネントは並行して実行されますが、送信中に相互に処理されません。「God Form」のアンチパターンにも注意する必要があります。他のすべての (目に見えない) 入力をまったく同じ形式で意図せずに処理/検証しないようにしてください (例:まったく同じ形式で必要な入力を含む隠しダイアログが表示されます)。こちらも参照 JSF ページで <h:form> を使用するにはどうすればよいですか?単一フォーム?複数のフォーム?入れ子になったフォーム?.いいえ
UIInput
値の検証/変換エラーが発生するはずです。使用できます<h:messages>
入力固有のメッセージでは表示されないメッセージを表示します。<h:message>
コンポーネント。を含めることを忘れないでくださいid
の<h:messages>
の中に<f:ajax render>
, 、ある場合は、ajax リクエストでも同様に更新されるようにします。こちらも参照 h:messages は、p:commandButton が押されたときにメッセージを表示しません.もし
UICommand
またはUIInput
コンポーネントは、次のような反復コンポーネント内に配置されます。<h:dataTable>
,<ui:repeat>
, など、まったく同じであることを確認する必要があります。value
反復コンポーネントの値は、フォーム送信リクエストのリクエスト値の適用フェーズ中に保持されます。JSF はそれを繰り返して、クリックされたリンク/ボタンと送信された入力値を見つけます。Bean をビュースコープに入れるか、データモデルを確実にロードするか、あるいはその両方@PostConstruct
Bean の (したがってゲッター メソッド内ではありません!) 問題は修正されるはずです。こちらも参照 h:dataTable のデータベースからモデルをいつどのようにロードする必要がありますか.もし
UICommand
またはUIInput
コンポーネントは、次のような動的ソースによってインクルードされます。<ui:include src="#{bean.include}">
, 、その後、まったく同じであることを確認する必要があります#{bean.include}
値は、フォーム送信リクエストのビュー構築時に保持されます。JSF は、コンポーネント ツリーの構築中にそれを再実行します。Bean をビュースコープに入れるか、データモデルを確実にロードするか、あるいはその両方@PostConstruct
Bean の (したがってゲッター メソッド内ではありません!) 問題は修正されるはずです。こちらも参照 ナビゲーションメニューによって動的インクルードコンテンツをAjax更新するにはどうすればよいですか?(JSFスパ).の
rendered
コンポーネントとそのすべての親の属性、およびtest
任意の親の属性<c:if>
/<c:when>
と評価すべきではないfalse
フォーム送信リクエストのリクエスト値の適用フェーズ中。JSF は、改ざん/ハッキングされたリクエストに対する保護の一環として、それを再チェックします。条件の原因となる変数を@ViewScoped
Bean または条件を適切に事前初期化していることを確認する@PostConstruct
の@RequestScoped
豆がそれを修正するはずです。同じことが、disabled
コンポーネントの属性。次のように評価すべきではありません。true
リクエスト値の適用フェーズ中。こちらも参照 JSF CommandButton アクションが呼び出されません そして 条件付きでレンダリングされたコンポーネントでのフォーム送信が処理されない.の
onclick
の属性UICommand
コンポーネントとonsubmit
の属性UIForm
コンポーネントは返すべきではありませんfalse
または JavaScript エラーが発生します。次の場合にはあるはずです<h:commandLink>
または<f:ajax>
また、ブラウザの JS コンソールに JS エラーが表示されないこと。通常、正確なエラー メッセージをグーグルで検索すると、すでに答えが得られます。こちらも参照 jQuery を PrimeFaces に追加すると、キャッチされない TypeError が発生する.JSF 2.x 経由で Ajax を使用している場合
<f:ajax>
または、例えばプライムフェイス<p:commandXxx>
, を持っていることを確認してください。<h:head>
の代わりにマスターテンプレートで<head>
. 。そうしないと、JSF は Ajax 関数を含む必要な JavaScript ファイルを自動的にインクルードできなくなります。これにより、ブラウザの JS コンソールで「mojarra が定義されていません」または「PrimeFaces が定義されていません」のような JavaScript エラーが発生します。こちらも参照 h:commandLink actionlistener は、f:ajax および ui:repeat と一緒に使用すると呼び出されません.Ajax を使用していて、送信された値が最終的に次のようになった場合
null
, 、次に、UIInput
そしてUICommand
対象となるコンポーネントは、<f:ajax execute>
または、例えば<p:commandXxx process>
, そうでない場合、それらは実行/処理されません。こちらも参照 <f:ajax> を <h:commandButton> に追加するときに、送信されたフォームの値がモデル内で更新されない そして PrimeFaces のプロセス/更新および JSF f:ajax 実行/レンダリング属性について.送信された値が依然として残っている場合は、
null
, Bean の管理に CDI を使用している場合は、正しいパッケージからスコープ アノテーションをインポートしていることを確認してください。そうでない場合、CDI はデフォルトで@Dependent
これにより、EL 式の評価ごとに Bean が効果的に再作成されます。こちらも参照 @SessionScoped Bean がスコープを失い、常に再作成され、フィールドが null になります そして JSF 2 アプリケーションのデフォルトのマネージド Bean スコープは何ですか?の親であれば、
<h:form>
とともにUICommand
ボタンが同じページ内の別のフォームからの ajax リクエストによって事前にレンダリング/更新されている場合、JSF 2.2 以前では最初のアクションは常に失敗します。2 番目以降のアクションは機能します。これは、次のように報告されているビューステート処理のバグが原因で発生します。 JSF 仕様問題 790 現在は JSF 2.3 で修正されています。古い JSF バージョンの場合は、JSF の ID を明示的に指定する必要があります。<h:form>
の中にrender
の<f:ajax>
. 。こちらも参照 h:commandButton/h:commandLink は最初のクリックでは機能せず、2 回目のクリックでのみ機能します.もし
<h:form>
もっているenctype="multipart/form-data"
ファイルのアップロードをサポートするために設定されている場合は、少なくとも JSF 2.2 を使用していること、またはマルチパート/フォームデータリクエストの解析を担当するサーブレットフィルターが適切に設定されていることを確認する必要があります。FacesServlet
最終的にはリクエスト パラメータをまったく取得できないため、リクエスト値を適用できません。このようなフィルターを構成する方法は、使用されているファイル アップロード コンポーネントによって異なります。トマホーク用<t:inputFileUpload>
, 、 チェック この答え そしてPrimeFacesの場合<p:fileUpload>
, 、 チェック この答え. 。または、実際にファイルをまったくアップロードしていない場合は、属性を完全に削除します。ことを確認してください。
ActionEvent
の議論actionListener
ですjavax.faces.event.ActionEvent
したがって、そうではありませんjava.awt.event.ActionEvent
, 、これはほとんどの IDE が最初のオートコンプリート オプションとして提案するものです。を使用する場合、引数がないのも間違っていますactionListener="#{bean.method}"
. 。メソッドに引数を入れたくない場合は、次を使用します。actionListener="#{bean.method()}"
. 。あるいは実際に使いたいのかもしれませんaction
の代わりにactionListener
. 。こちらも参照 アクションとアクションリスナーの違い.そうでないことを確認してください
PhaseListener
または任意のEventListener
リクエストとレスポンスのチェーンで、たとえば次の呼び出しによってアクションの呼び出しフェーズをスキップするように JSF ライフサイクルが変更されました。FacesContext#renderResponse()
またはFacesContext#responseComplete()
.そうでないことを確認してください
Filter
またはServlet
同じ要求/応答チェーン内で、次の要求がブロックされました。FacesServlet
どうにか。PrimeFaces を使用している場合
<p:dialog>
または<p:overlayPanel>
, 次に、独自のものがあることを確認します。<h:form>
. 。これらのコンポーネントはデフォルトで JavaScript によって HTML の末尾に再配置されるためです。<body>
. 。つまり、彼らがもともと室内に座っていたとしたら、<form>
, そうすれば、彼らはもう座ることはできなくなります。<form>
. 。こちらも参照 p:commandbutton アクションが p:dialog 内で機能しないフレームワークのバグ。たとえば、RichFaces には「変換エラー"を使用するとき
rich:calendar
UI 要素defaultLabel
属性 (場合によっては、rich:placeholder
サブ要素)。このバグにより、暦日の値が設定されていない場合、Bean メソッドが呼び出されなくなります。フレームワークのバグを追跡するには、単純な動作例から始めて、バグが発見されるまでページのバックアップを構築します。
デバッグのヒント
それでも問題が解決しない場合は、デバッグしてみましょう。クライアント側で、Web ブラウザで F12 を押して Web 開発者ツールセットを開きます。クリック コンソール タブなので、JavaScript コンソールを参照してください。JavaScript エラーがないことが必要です。以下のスクリーンショットは、Chrome からの例であり、 <f:ajax>
ボタンがない場合に有効化 <h:head>
(上記のポイント 7 で説明したように) 宣言されています。
クリック 通信網 タブをクリックして、HTTP トラフィック モニターを表示します。フォームを送信し、リクエスト ヘッダー、フォーム データ、および応答本文が期待どおりであるかどうかを調査します。以下のスクリーンショットは、単一のシンプルなフォームの成功した ajax 送信を示す Chrome の例です。 <h:inputText>
そしてシングル <h:commandButton>
と <f:ajax execute="@form" render="@form">
.
(警告:運用環境から上記のような HTTP リクエスト ヘッダーのスクリーンショットを投稿する場合は、セッション ハイジャック攻撃を避けるために、スクリーンショット内のセッション Cookie を必ずスクランブル/難読化してください。)
サーバー側では、サーバーがデバッグ モードで起動されていることを確認します。フォーム送信の処理中に呼び出されることが予想される対象の JSF コンポーネントのメソッドにデバッグ ブレークポイントを設定します。例えば。の場合には UICommand
コンポーネント、つまり UICommand#queueEvent()
そして、の場合 UIInput
コンポーネント、つまり UIInput#validate()
. 。コードをステップ実行して、フローと変数が期待どおりであるかどうかを検査するだけです。以下のスクリーンショットは、Eclipse のデバッガーの例です。
他のヒント
あなたのh:commandLink
はh:dataTable
内h:commandLink
が動作しない場合があります別の理由があるされている場合:
h:dataTable
に結合され、基礎となるデータ・ソースは、リンクをクリックしたときにトリガされる第二のJSF-ライフサイクルに利用可能でなければならない。
だから、基礎となるデータ・ソースは、要求がスコープされている場合、h:commandLink
は仕事をしません!
、私はそれがnontheless投稿することを決めます:
あなたはのPrimeFacesの(またはいくつかの類似したAPI)p:commandButton
またはp:commandLink
を使用している場合は、、チャンスはあなたが明示的にコマンド・コンポーネントにprocess="@this"
を追加します。
PrimeFacesユーザーズガイドは、セクション3.18に述べているように、process
とupdate
のデフォルトはかなりそれぞれ@form
とf:ajax
あるあなたは普通のJSFのexecute="@this"
やRichFacesのから期待するかもしれないデフォルトを、反対の両方render="@none"
、です。
だけは私を見つけるためにlooong時間がかかりました。 (...と私はそれがJSF異なるデフォルトを使用することではなくuncleverだと思います!)
Primefaces に関してもう 1 つ言及したいと思います。 p:commandButton
!
を使用するときは、 p:commandButton
サーバー上で実行する必要があるアクションには、使用できません type="button"
それはのためだから ボタンを押す これは、サーバーに対して ajax/非 ajax リクエストを発生させずにカスタム JavaScript を実行するために使用されます。
この目的のために、 type
属性 (デフォルト値は "submit"
) または明示的に使用できます type="submit"
.
これが誰かの役に立つことを願っています!
ガットは、この問題を自分自身を立ち往生し、この問題のもう一つの原因を発見しました。 あなたは* .xhtmlに使用されるプロパティのためのあなたのバッキングBeanでセッターメソッドを持っていない場合、アクションは単純に呼び出されません。
私は最近のUICommandで問題に遭遇したIBM拡張の顔にコンポーネントを使用してJSF 1.2アプリケーションで呼び出すことではない。
私は(<hx:datatable>
ように、拡張バージョン)データテーブルの行にコマンドボタンを持っていたとのUICommandテーブルから特定の行(行のない火であろうと希望しない火災デフォルトの行表示よりも行大きかったですサイズ)。
Iは、表示する行数を選択するためのドロップダウン成分を有していました。このフィールドバッキング値はRequestScope
にありました。テーブル自体をバックアップデータ(一時ViewScope
で、実際に)SessionScope
の一種であった。
rows
属性にバインドされたコントロールを経由して増加した場合は、クリックするとは、行のどれものUICommandを発射でき、この変更の結果として表示されません。
自体が問題を修正したテーブルデータと同じ範囲内でこの属性を配置する。
私は、これはBalusC#上記4にまで言及していると思いますが、唯一のビューやセッションスコープはなくなるように、テーブル値の必要性をやっていないにもそのテーブルの上に表示する行数を制御する属性ます。
私もこの問題を抱えていたとだけは本当にブラウザのWebコンソールを開いた後に根本的な原因の中に磨くために始めました。それまでは、私は(さえ<p:messages>
付き)すべてのエラーメッセージを取得できませんでした。 Webコンソールは<h:commandButton type="submit" action="#{myBean.submit}">
から戻ってくるHTTP 405ステータスコードを示します。
私の場合、私はバニラのHttpServletのは、私のアプリケーションビューとビジネスロジックを実行するAuth0とJSFのFaceletsと豆を経由してOAuth認証を提供します。
が混在しています 私は私のweb.xmlをリファクタリングし、仲介人・サーブレットを削除と、それはその後、「魔法」働いていました。
ボトムライン、問題は前それに呼び出されるサーブレットは移す際にHttpServletResponse.sendRedirectにリダイレクトされたのに対し、中間の男 - サーブレットがJSF環境にHttpServletの環境からリダイレクトするのRequestDispatcher.forwardを(...)使用していたということでした(...)。
基本的には、()のsendRedirectを使用)のRequestDispatcher.forward(一方の制御を取るためにJSF "コンテナ" を許可さ明らかではなかった。
どのようにfaceletがBeanのプロパティにアクセスすることができましたが、それらを設定することができませんでした、これは明らかに、サーブレットとJSFのミックスと離れて行うために叫ぶが、私はこれが誰かの回避多くの時間を役に立てば幸い私はなぜ知っているしていません頭 - テーブルバンギングます。
私は<h:commandLink>
のrichfaces
でdatatable
のアクションが火に拒否した問題をデバッグするたくさんの楽しみを持っていました。テーブルには、いくつかの点での作業に使用されるが、明らかな理由もなく停止しました。私は私のrich:datatable
は喜んで行キーとして使用するRichFacesのNULLを返された間違ったrowKeyConverter
を使用していたことを見つけるために、あらゆる手段なしの石を残しませんでした。これは呼ばれる得ることから私の<h:commandLink>
アクションを妨げます。
もう 1 つの可能性:最初の呼び出しは機能するが、その後の呼び出しは機能しないという症状がある場合は、ここで詳しく説明されているように、PrimeFaces 3.x と JSF 2.2 を使用している可能性があります。 ViewState は送信されません.
私は置くと私の問題を修正しました
<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>
<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>