時々、<h:commandLink>
、<h:commandButton>
または<f:ajax>
を使用するとき、タグに関連したaction
、actionListener
またはlistener
メソッドは単に呼び出されていません。または、Beanプロパティが送信されたUIInput
値で更新されていません。
考えられる原因と解決策は何ですか?
UICommand
コンポーネント(<h:commandXxx>
、<p:commandXxx>
など)が関連付けられたアクションメソッドの呼び出しに失敗した場合、またはUIInput
コンポーネント(<h:inputXxx>
、<p:inputXxxx>
など)が送信された値の処理またはモデル値の更新に失敗した場合JSF ajaxリクエストで例外処理 を使用してajax例外ハンドラーを構成した場合 、または以下のcontextパラメーターを設定した場合も、サーバーログ内の検索可能な例外や警告は発生しません。 web.xml
、
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
また、ブラウザのJavaScriptコンソールにgooglableなエラーや警告が表示されず(Chrome/Firefox 23 +/IE 9 +でF12キーを押してWeb開発者用ツールセットを開き、次にConsoleタブを開く)、次に進みます。考えられる原因のリストの下に。
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>
コンポーネントによって表示されないメッセージを表示できます。 ajaxリクエストでも更新されるように、<h:messages>
のid
を<f:ajax render>
に含めることを忘れないでください。 も参照してください。h:messagesは、p:commandButtonが押されたときにメッセージを表示しません 。
UICommand
またはUIInput
コンポーネントが<h:dataTable>
、<ui:repeat>
などの反復コンポーネント内に配置されている場合は、フォームsubmit requestの要求値の適用フェーズで、反復コンポーネントとまったく同じvalue
を確実に保持する必要があります。 JSFはそれを繰り返してクリックされたリンク/ボタンを見つけ、入力値を送信します。 Beanをビュースコープに配置するか、データモデルをBeanの@PostConstruct
にロードしたことを確認してください(したがってgetterメソッドには含まれていません)。また、 を参照してください。h:dataTable については、データベースからモデルをいつどのようにロードする必要があります。
UICommand
またはUIInput
コンポーネントが<ui:include src="#{bean.include}">
などの動的ソースに含まれている場合は、フォーム送信要求のビュー構築時に、まったく同じ#{bean.include}
値が保持されるようにする必要があります。 JSFはコンポーネントツリーの構築中にそれを再実行します。 Beanをビュースコープに配置するか、データモデルをBeanの@PostConstruct
にロードしたことを確認してください(したがってgetterメソッドには含まれていません)。ナビゲーションメニューで動的インクルードコンテンツをajax-refreshする方法は? もご覧ください。 (JSF SPA) .
コンポーネントおよびそのすべての親のrendered
属性、および任意の親のtest
属性<c:if>
/<c:when>
は、フォーム送信要求の要求値適用フェーズ中にfalse
に評価されるべきではありません。 JSFは改ざんやハッキングされたリクエストに対する保護策の一部としてそれを再確認します。 @ViewScoped
ビーンに条件に責任がある変数を格納するか、@PostConstruct
ビーンの@RequestScoped
に条件を適切に事前初期化していることを確かめることはそれを修正するべきです。同じことがコンポーネントのdisabled
属性にも当てはまります。これは、要求値の適用フェーズ中にtrue
に評価されるべきではありません。参照 JSF CommandButtonアクションが呼び出されない および 条件付きでレンダリングされたコンポーネントのフォーム送信が処理されない 。
onclick
コンポーネントのUICommand
属性およびonsubmit
コンポーネントのUIForm
属性は、false
を返したり、JavaScriptエラーを引き起こしたりするべきではありません。 <h:commandLink>
または<f:ajax>
の場合も、ブラウザのJSコンソールにはJSエラーが表示されないはずです。通常正確なエラーメッセージをグーグルすることは既にあなたに答えを与えるでしょう。 PrimeFacesにjQueryを追加すると、すべての場所でUncaught TypeErrorが発生します 。
もしあなたがJSF 2.x <f:ajax>
経由でAjaxを使っているなら、またはPrimeFaces <p:commandXxx>
は、マスターテンプレートに<h:head>
ではなく<head>
があることを確認してください。そうでなければ、JSFはAjax関数を含む必要なJavaScriptファイルを自動インクルードすることができません。これにより、ブラウザのJSコンソールで "mojarraが定義されていません"または "PrimeFacesが定義されていません"などのJavaScriptエラーが発生します。 も参照してください。h:commandLink actionlistenerは、f:ajaxおよびui:repeat と共に使用した場合は呼び出されません。
Ajaxを使用している場合は、目的のUIInput
およびUICommand
コンポーネントが<f:ajax execute>
でカバーされていることを確認してください。 <p:commandXxx process>
、それ以外の場合は実行または処理されません。参照 <f:ajax>を<h:commandButton> および に追加したときに送信されたフォーム値がモデル内で更新されないPrimeFcesのprocess/updateおよびJSFについて:ajax実行/レンダリング属性 .
UICommand
ボタンを持つ<h:form>
の親が、同じページ内の別のフォームからのajaxリクエストによって事前にレンダリング/更新されている場合、最初のアクションは常に失敗します。 2番目以降のアクションは機能します。これは、 JSF仕様の問題790 として報告され、現在JSF 2.3で修正される予定のビューステート処理のバグが原因です。古いバージョンのJSFでは、<h:form>
のrender
に<f:ajax>
のIDを明示的に指定する必要があります。 も参照してください。h:commandButton/h:commandLinkは1回目のクリックでは機能せず、2回目のクリックでのみ機能します 。
ファイルのアップロードをサポートするために<h:form>
にenctype="multipart/form-data"
が設定されている場合は、少なくともJSF 2.2を使用していること、またはマルチパート/フォームデータ要求の解析を担当するサーブレットフィルタが正しく設定されていることを確認する必要があります。 FacesServlet
はリクエストパラメータをまったく取得しないため、リクエスト値を適用できません。このようなフィルタの設定方法は、使用されているファイルアップロードコンポーネントによって異なります。 Tomahawk <t:inputFileUpload>
の場合、この回答をチェック し 、PrimeFacesの<p:fileUpload>
の場合、この回答をチェック します 。または、実際にファイルをまったくアップロードしていない場合は、属性をすべて削除します。
ActionEvent
のactionListener
引数がjavax.faces.event.ActionEvent
であり、したがってJava.awt.event.ActionEvent
ではないことを確認してください。これは、ほとんどのIDEが1番目のオートコンプリートオプションとして推奨するものです。 actionListener="#{bean.method}"
を使用している場合も、引数がないことは間違っています。メソッドに引数が必要ない場合はactionListener="#{bean.method()}"
を使用してください。あるいは、実際にはaction
の代わりにactionListener
を使いたいと思うかもしれません。 actionとactionListenerの違い も参照してください。
要求 - 応答チェーン内のPhaseListener
またはEventListener
が、アクション呼び出しフェーズをスキップするようにJSFライフサイクルを変更していないことを確認します。たとえば、FacesContext#renderResponse()
またはFacesContext#responseComplete()
を呼び出します。
同じ要求 - 応答チェーン内のFilter
またはServlet
が、何らかの理由でFacesServlet
の要求をブロックしていないことを確認してください。
フレームワークのバグたとえば、defaultLabel
属性を持つrich:calendar
UI要素(または場合によってはrich:placeholder
サブ要素)を使用すると、RichFacesには「 変換エラー 」が表示されます。このバグは、カレンダ日付に値が設定されていないときにBeanメソッドが呼び出されないようにします。フレームワークのバグのトレースは、簡単な実用的な例から始めて、バグが見つかるまでページを元に戻すことによって実現できます。
PrimeFaces <p:dialog>
または<p:overlayPanel>
を使用している場合は、それらが独自の<h:form>
を持っていることを確認してください。なぜなら、これらのコンポーネントはデフォルトでJavaScriptのHTMLの末尾に移動した<body>
です。そのため、元々<form>
の内側に座っていたのであれば、もはや<form>
の中に座っていないでしょう。 も参照してください。p:commandbuttonアクションはp:dialog内では機能しません
それでも動けない場合は、デバッグする時が来ました。クライアントサイドでは、WebブラウザでF12キーを押してWeb開発者ツールセットを開きます。 Consoleタブをクリックして、JavaScriptコンソールを見てください。 JavaScriptのエラーがないことを確認してください。下のスクリーンショットはChromeからの例です。これは、<f:ajax>
が宣言されていないのに<h:head>
対応ボタンを送信するケースを示しています(上記のポイント7で説明)。
HTTPトラフィックモニタを表示するには、Networkタブをクリックします。フォームを送信して、要求ヘッダーとフォームデータ、および応答本文が予想どおりかどうかを調べます。以下のスクリーンショットはChromeからの例で、単一の<h:inputText>
と単一の<h:commandButton>
および<f:ajax execute="@form" render="@form">
を含む単純なフォームのajax送信が成功したことを示しています。
(警告:本番環境から上記のようなHTTPリクエストヘッダからスクリーンショットを投稿するときは、セッションハイジャック攻撃を避けるためにスクリーンショットのセッションクッキーをスクランブル/難読化してください。)
サーバー側で、サーバーがデバッグモードで起動されていることを確認します。フォーム送信の処理中に呼び出されることが予想される、関心のあるJSFコンポーネントのメソッドにデバッグブレークポイントを設定します。例えば。 UICommand
コンポーネントの場合は、 UICommand#queueEvent()
となり、UIInput
コンポーネントの場合は、 UIInput#validate()
となります。コードの実行を一通り行い、フローと変数が予想どおりであるかどうかを調べます。下のスクリーンショットはEclipseのデバッガの例です。
あなたのh:commandLink
がh:dataTable
の内側にある場合、h:commandLink
が機能しないかもしれないもう一つの理由があります:
h:dataTable
にバインドされている基礎となるデータソースは、リンクがクリックされたときにトリガーされる2番目のJSFライフサイクルでも利用可能でなければなりません。
そのため、基になるデータソースがスコープ指定のリクエストである場合、h:commandLink
は機能しません。
私の答えは100%当てはまるわけではありませんが、ほとんどの検索エンジンはこれを最初のヒットとして見つけていますが、それでも投稿することにしました。
PrimeFaces(またはそれに類するAPI)のp:commandButton
またはp:commandLink
を使用している場合は、process="@this"
をコマンドコンポーネントに明示的に追加するのを忘れている可能性があります。
『PrimeFacesユーザガイド』のセクション3.18に記載されているように、process
とupdate
のデフォルトはどちらも@form
であり、プレーンJSFのf:ajax
またはRichFaces(それぞれexecute="@this"
およびrender="@none"
)から予想されるデフォルトとはまったく反対です。
調べるのにちょうど私の時間がかかりました。 (...そして、JSFとは異なるデフォルトを使用するのはどちらかというと不明瞭です!)
Primefacesのp:commandButton
に関するもう1つのことを述べます。
サーバーで実行する必要があるアクションにp:commandButton
を使用する場合は、type="button"
を使用できません。 ボタンを押す これは、サーバーへのajax/non -jaxリクエストを引き起こさずにカスタムjavascriptを実行するために使用されます。
この目的のために、type
属性を省略すること(デフォルト値は"submit"
)または明示的にtype="submit"
を使用することができます。
これが誰かに役立つことを願っています!
私は最近、UICommandがIBM Extended Faces Componentsを使用してJSF 1.2アプリケーションを呼び出さないという問題に遭遇しました。
データテーブルの行にコマンドボタンがあり(拡張バージョンなので<hx:datatable>
)、UICommandはテーブルの特定の行から起動しません(起動しない行はデフォルトの行表示サイズより大きい行でした)。
表示する行数を選択するためのドロップダウンコンポーネントがありました。このフィールドの背後にある値はRequestScope
にありました。テーブル自体を裏付けるデータは一種のViewScope
にありました(実際には、一時的にSessionScope
に入っていました)。
どの値がデータテーブルのrows
属性にもバインドされているかによってコントロールを介して行の表示が増えた場合、この変更の結果として表示される行はどれもクリック時にUICommandを起動できません。
この属性をテーブルデータ自体と同じスコープに配置することで問題は解決しました。
これは上記のBalusC#4で示唆されていると思いますが、テーブルの値はViewまたはSessionスコープである必要があるだけでなく、そのテーブルに表示する行数を制御する属性も必要です。
私自身がこの問題に立ち往生しており、この問題のもう1つの原因を見つけました。バッキングBeanに* .xhtmlで使用されているプロパティの設定メソッドがない場合は、単純にアクションは呼び出されません。
私もこの問題を抱えていて、ブラウザのWebコンソールを開いた後に、根本的な原因に集中し始めました。それまでは、(<p:messages>
でも)エラーメッセージを受け取ることができませんでした。 Webコンソールは<h:commandButton type="submit" action="#{myBean.submit}">
から戻ってくるHTTP 405ステータスコードを示しました。
私の場合は、Auth0を介したOAuth認証を提供するVanilla HttpServletとJSFファセットおよびBeanを組み合わせて、私のアプリケーションビューとビジネスロジックを実行しています。
Web.xmlをリファクタリングし、middle-man-servletを削除すると、それは「魔法のように」機能しました。
結論として、問題は、middle-man-servletがRequestDispatcher.forward(...)を使用してHttpServlet環境からJSF環境にリダイレクトしていたのに対し、それ以前に呼び出されていたサーブレットはHttpServletResponse.sendRedirect(..)でリダイレクトされていたことです。 。).
基本的に、sendRedirect()を使用するとJSFの「コンテナ」が制御を取得できましたが、RequestDispatcher.forward()は明らかにそうではありませんでした。
わからないのは、なぜfaceletがbeanプロパティにアクセスできたが設定できなかったのか、そしてこれが明らかにservletsとJSFの混在をなくすことを叫んでいることです。テーブルバンギング。
もう1つの可能性:症状が最初の呼び出しは機能するがそれ以降の機能が機能しないことである場合、ここで詳述するように、JSF 2.2でPrimeFaces 3.xを使用している可能性があります。 ViewStateは送信されません 。
richfaces
datatable
内の<h:commandLink>
のアクションが起動を拒否したという問題をデバッグするのはとても楽しいことでした。このテーブルは以前は動作していましたが、明らかな理由もなく停止しました。私のrich:datatable
が間違ったrowKeyConverter
を使っていたことを知るためだけに、私は何の問題もありませんでした。これは私の<h:commandLink>
アクションが呼ばれるのを防ぎました。