送信すると、応答のレンダリング中にjavascriptを使用してすべてのボタンを無効にする必要があります。
これは、一般的な方法で実装するのが最も簡単です。<f:ajax>
排他的に使用する場合は、を使用jsf.ajax.addOnEvent()
して一般的な方法でジョブを実行できます。別のJavaScriptアプローチは、UIをブロックする一種の「読み込み中」オーバーレイを作成して、エンドユーザーが基になるページを操作できなくなるようにすることです。これは基本的に、<div>
ビューポート全体にいくらかopacity
(透明度)を広げて、完全に隠された位置にあります。送信時に表示し、レンダリング時に非表示にすることができます。この手法のキーワードは「モーダルダイアログ」です。UI指向のJSFコンポーネントライブラリには、少なくともそのようなコンポーネントがすでに含まれています。例:PrimeFacesの<p:dialog modal="true">
内部に、、<p:ajaxStatus>
または<p:blockUI>
唯一の欠点は、クライアントでJSが無効になっている場合、またはJSを使用していない場合は機能しないため、HTTPクライアントによる二重送信が妨げられないことです。
セッションスコープ内のフラグは、すでにアクティブになっていることを示しているため、機密コードはスキップされ、前の送信の応答の再レンダリングに進みます。
これは「シンクロナイザートークンパターン」として知られ、現在2.2を対象とするチケットに含まれている仕様の問題559によってJSFに要求されたことがありますが、アクティビティはないようです。検出とブロックの部分は技術的に実装が簡単ですが、エンドユーザーが最初の要求によって生成された応答を最終的に取得するようにしたい場合、同期応答処理の部分は実装が簡単ではありません。非同期応答の処理は簡単です。更新するコンポーネントを指定しないでください。つまり、によって返されるコレクションを空にしPartialViewContext#getRenderIds()
ます。結局のところ、これはJSを使用してボタンを無効にしたりUIをブロックしたりするよりも堅牢です。
私の知る限り、このために再利用可能なJSFコンポーネントを提供したのはSeam2だけでした<s:token>
。ただし、これは新しいOmniFacesコンポーネントにとって興味深いアイデアであることを認めなければなりません。多分私はそれを個人的に見ていきます。
前の要求が終了するまで処理を遅らせる同期ブロック。次に、それがすでに処理されてスキップされたことを検出する必要があります。
これを一般的に実装するのは簡単ではありません。これには、ジョブがすでに完了しているかどうかを確認するために、すべてのアクションメソッドを変更する必要があります。また、Webアプリが複数のサーバーで実行されている場合も機能しません。シンクロナイザートークンは、アクションメソッドが呼び出される前に実行されるため、簡単です。シンクロナイザートークンは、スレッド/リソースのみを消費するキュー内の複数のリクエストで終了しないため、より安価です。
変換などの「新しい」スコープの1つを使用して、検出を処理しますか?
この問題は、マネージドBeanスコープを試してみても解決できません。マネージドBeanスコープは、Beanインスタンスの存続期間という別の目的を果たします。