<h:commandLink>
場合によっては、 、<h:commandButton>
またはを使用すると<f:ajax>
、タグに関連付けられたaction
、actionListener
または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 開発者ツールセットを開き、[コンソール]タブを開きます)、以下の考えられる原因のリストを確認してください。
考えられる原因
UICommand
また、コンポーネントはコンポーネントUIInput
内に配置する必要があります(つまり、プレーン HTML ではありません)。そうしないと、サーバーに何も送信されません。コンポーネントには属性も設定できません。そうしないと、JavaScript でのみ有効なデッドボタンになります。UIForm
<h:form>
<form>
UICommand
type="button"
onclick
フォーム入力値を送信し、JSF Bean でメソッドを呼び出す方法そして<h:commandButton> はポストバックを開始しません。UIForm
複数のコンポーネントを互いにネストすることはできません。これは HTML では違法です。ブラウザの動作は未指定です。インクルード ファイルには注意してください。UIForm
コンポーネントを並行して使用できますが、送信時に相互に処理されません。また、「God Form」アンチパターンにも注意する必要があります。同じフォームで他のすべての (非表示の) 入力を意図せずに処理/検証しないようにします (たとえば、同じフォームで必要な入力を含む非表示のダイアログがあるなど)。参照:JSF ページで <h:form> を使用するには? 単一のフォームですか? 複数のフォームですか? ネストされたフォームですか?。UIInput
値の検証/変換エラーは発生していないはずです。 を使用すると、入力固有のコンポーネントで表示されないメッセージを表示できます。<h:messages>
がある場合は、に を含める<h:message>
ことを忘れないでください。これにより、Ajax リクエストでも更新されます。 も参照してください。id
<h:messages>
<f:ajax render>
h:messages は p:commandButton が押されたときにメッセージを表示しません。UICommand
またはコンポーネントが、、などUIInput
の反復コンポーネント内に配置されている場合は、フォーム送信リクエストのリクエスト値適用フェーズ中に、反復コンポーネントのまったく同じものが保持されていることを確認する必要があります。JSF は、クリックされたリンク/ボタンと送信された入力値を見つけるためにそれを繰り返します。Bean をビュー スコープに配置するか、Bean のデータ モデルをロードする (つまり、ゲッター メソッド内ではない) ことで、この問題を修正できます。<h:dataTable>
<ui:repeat>
value
@PostConstruct
JSF データテーブルのモデルをデータベースからいつどのようにロードすればよいですか。UICommand
またはUIInput
コンポーネントが などの動的ソースによってインクルードされる場合<ui:include src="#{bean.include}">
、フォーム送信リクエストのビュー構築時にまったく同じ値が保持されるようにする必要があります#{bean.include}
。JSF はコンポーネント ツリーの構築中にこれを再実行します。Bean をビュー スコープに配置するか、@PostConstruct
Bean のデータ モデルをロードする (つまり、ゲッター メソッド内ではない) ことで、この問題を修正できます。ナビゲーション メニューで動的にコンテンツを含めるには、どのように Ajax を更新すればよいですか? (JSF SPA)。rendered
コンポーネントとそのすべての親の属性、および任意test
の親<c:if>
/の属性は、フォーム送信リクエストのリクエスト値の適用フェーズで に<c:when>
評価されるべきではありません。JSF は、改ざんされた/ハッキングされたリクエストに対する保護策の一環としてこれを再チェックします。条件に関係する変数を Bean に格納するか、Beanの条件を適切に事前初期化することで、この問題を修正できます。同じことがコンポーネントのおよび属性にも当てはまります。これらは、リクエスト値の適用フェーズで に評価されるべきではありません。次も参照してください。false
@ViewScoped
@PostConstruct
@RequestScoped
disabled
readonly
true
JSF コマンドボタンアクションが呼び出されませんでした、条件付きでレンダリングされたコンポーネントのフォーム送信は処理されません、h:commandButton は、<h:panelGroup rendered> でラップすると機能しなくなります。そしてとにかく、JSF に読み取り専用/無効な入力コンポーネントを処理、検証、更新するように強制します。onclick
コンポーネントの属性とUICommand
コンポーネントonsubmit
の属性は、JavaScript エラーをUIForm
返したり、エラーを引き起こしたりしてはなりません。また、ブラウザの JS コンソールに JS エラーが表示されないようにする必要があります。通常、正確なエラー メッセージを Google で検索すると、答えが見つかります。false
<h:commandLink>
<f:ajax>
PrimeFaces で jQuery を手動で追加 / ロードすると、Uncaught TypeErrors が発生します。。<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 と併用すると呼び出されません。。Ajax を使用していて、送信された値が になったり
null
、コマンドが呼び出されなかったりする場合は、対象のUIInput
およびコンポーネントがまたは (例)でカバーされていることを確認してください。そうでない場合、実行/処理されません。以下も参照してください。UICommand
<f:ajax execute>
<p:commandXxx process>
<f:ajax> を <h:commandButton> に追加しても、送信されたフォームの値がモデル内で更新されないそしてPrimeFaces のプロセス/更新と JSF f:ajax の実行/レンダリング属性を理解する。送信された値が依然として になり
null
、CDI を使用して Bean を管理している場合は、正しいパッケージからスコープ注釈をインポートしていることを確認してください。そうしないと、CDI はデフォルトで になり、@Dependent
EL 式の評価ごとに Bean が効果的に再作成されます。@SessionScoped Bean はスコープを失い、常に再作成され、フィールドが null になります。そしてJSF 2 アプリケーションのデフォルトのマネージド Bean スコープとは何ですか?<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 回目のクリックでのみ機能します。。がファイルのアップロードをサポートするように設定されている
<h:form>
場合、少なくとも JSF 2.2 を使用しているか、multipart/form-data リクエストの解析を担当するサーブレット フィルタが適切に設定されていることを確認する必要があります。そうでない場合、 はリクエスト パラメータをまったく取得できず、リクエスト値を適用できなくなります。このようなフィルタの設定方法は、使用されているファイル アップロード コンポーネントによって異なります。Tomahawk の場合は、以下を確認してください。enctype="multipart/form-data"
FacesServlet
<t:inputFileUpload>
この答えPrimeFacesの場合は<p:fileUpload>
、この答えまたは、実際にファイルをアップロードしない場合は、属性を完全に削除します。ActionEvent
の引数actionListener
が であり、ほとんどの IDE が最初の自動補完オプションとして提案する でjakarta.faces.event.ActionEvent
はないことを確認してくださいjava.awt.event.ActionEvent
。 を使用する場合、引数がないのも間違いですactionListener="#{bean.method}"
。 メソッドに引数が必要ない場合は を使用してください。または、の代わりにactionListener="#{bean.method()}"
を使用する必要があるかもしれません。 も参照してください。action
actionListener
actionとactionListenerの違い。要求応答チェーン内の
PhaseListener
いずれの も、またはを呼び出すなどして、JSF ライフサイクルを変更して呼び出しアクション フェーズをスキップしていないことを確認します。EventListener
FacesContext#renderResponse()
FacesContext#responseComplete()
同じリクエスト レスポンス チェーン内の
Filter
または が何らかの方法でリクエストをブロックしていないことを確認します。たとえば、Spring Security などのログイン/セキュリティ フィルターなどです。特に、デフォルトでは UI フィードバックがまったく行われない Ajax リクエストではそうです。Servlet
FacesServlet
Spring Security 4 と PrimeFaces 5 の AJAX リクエスト処理。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 で説明)。
[ネットワーク]タブをクリックして、HTTP トラフィック モニターを表示します。フォームを送信し、リクエスト ヘッダーとフォーム データ、および応答本文が期待どおりであるかどうかを調べます。以下のスクリーンショットは、1 つの<h:inputText>
と 1 つの<h:commandButton>
を含む単純なフォームの Ajax 送信が成功したことを示す Chrome の例です<f:ajax execute="@form" render="@form">
。
(警告: 上記のような HTTP リクエスト ヘッダーのスクリーンショットを本番環境から投稿する場合は、セッション ハイジャック攻撃を回避するために、スクリーンショット内のすべてのセッション クッキーをスクランブル/難読化してください。)
サーバー側では、サーバーがデバッグモードで起動されていることを確認します。フォーム送信の処理中に呼び出されると予想されるJSFコンポーネントのメソッドにデバッグブレークポイントを設定します。たとえば、UICommand
コンポーネントの場合は次のようになります。UICommand#queueEvent()
UIInput
コンポーネントの場合は、UIInput#validate()
コード実行をステップ実行し、フローと変数が期待どおりであるかどうかを検査します。以下のスクリーンショットは、Eclipse のデバッガーからの例です。