ブラウザの画面でボタンを何度か押した場合に、サーバーへのリクエストが複数回発行されます。このとき、処理が二重に実行されることを防止する機能をApcoordinatorは提供しています。
二重処理を防止する機能にはブラウザ側で処理するものと、サーバー側で処理するものがあります。
ブラウザ側で二重処理を防止する
JavaScriptを利用して、フォーム送信時にフラグを立てることにより、同じ画面から再度送信することを防ぎます。
サーバー側で二重処理を防止する
uji:dispatchタグ実行中に同じセションから別のリクエストが送信された場合に、後者のリクエストを実行しません。その結果、二重処理が防止されます。最初のリクエストの実行結果が、後者のリクエストへの応答としてブラウザに送信されます。
2つの機能の長所、短所を比較すると以下のようになります。
ブラウザ側での処理の場合、JavaScriptが無効になっている場合は使用できません。サーバー側での処理の場合、JavaScriptの有無に関わらず動作します。
サブウィンドウやフレーム分割によって複数の画面を使用している場合、ブラウザ側の処理では、別の画面からのリクエストによる二重処理は防止できません。サーバー側の処理の場合、同じセションからのリクエストなら画面によらず防止できます。
サーバー側での処理の場合、ビジネスクラス呼び出し中の二重処理は防止できますが、uji:dispatch以降のJSP実行中(画面表示処理中)の二重処理は防止できません。ブラウザ側の処理の場合、ビジネスクラス、JSP実行を含め全体の二重処理が防止できます。
ブラウザ側で二重処理を防止する
uji:formタグでフォームを作成し、postOnceアトリビュートに"true"を指定します。
<uji:form name="order" method="post" postOnce="true" verbs="ok,cancel" beanId="body" beanCls="my.pkg.MyDataBean">
商品コード: <INPUT NAME="code"><BR>
個数: <INPUT NAME="count"><BR>
<INPUT TYPE="SUBMIT" NAME="ok" VALUE="決定">
<INPUT TYPE="SUBMIT" NAME="cancel" VALUE="キャンセル">
</uji:form>
postOnce="true"を指定した場合、ブラウザの読み込みが中断されたあとでも二重処理防止機能が有効になっています。そのため、次の画面が表示される前に読み込み停止ボタンなどを押して送信処理を中断し、そのあとで送信ボタンを押した場合はフォームが送信されません。このような状態に備えて、postOnce="true"の指定の有無にかかわらずフォームの送信できる送信ボタンを作成できます。送信ボタンをuji:pushButtonタグで作成し、skipScript="true"を指定してください。
<uji:form name="order" method="post" postOnce="true" verbs="ok,cancel" beanId="body" beanCls="my.pkg.MyDataBean"> 商品コード: <INPUT NAME="code"><BR> 個数: <INPUT NAME="count"><BR> <INPUT TYPE="SUBMIT" NAME="ok" VALUE="決定"> <uji:pushButton type="submit" name="cancel" label="キャンセル" skipScript="true" /> </uji:form>
skipScript="true"の指定は、フォーム送信時のJavaScriptの実行を抑止するための機能です。この指定のあるボタンが押された場合は、二重処理を防止するJavaScriptだけでなく、入力値をチェックするJavaScriptも実行されません。
サーバー側で二重処理を防止する
サーバー側で二重処理を防止するには、アプリケーションを以下のように作成します。
HttpControlStateProfileクラスを継承して、ユーザー定義のセションクラスを作成します。
すべてのフォームにuji:controlStateタグを追加します。
この2つを順に説明します。
ユーザー定義のセションクラスをcom.fujitsu.uji.http.HttpControlStateProfileクラスを継承して作成します。また、isDoublePostEnabled メソッドをオーバライドしてfalseを返却するようにします。このメソッドは、二重処理を認めるかどうかを指定するものです。
public class SampleSession extends com.fujitsu.uji.http.HttpControlStateProfile { public boolean isDoublePostEnabled() { return false; } }
なお、ユーザー定義のセションクラスを有効にするために、以下の作業が必要になります。具体的な方法は“3.5 ファクトリクラス”を参照してください。
ファクトリクラスを作成し、ユーザー定義セションクラスのオブジェクトが作成されるようにします。
初期化パラメタでファクトリクラスのクラス名を指定します。Webアプリケーションの初期化パラメタはWebアプリケーション環境定義ファイル(web.xml)に記述します。
以下のように、すべてのフォームにuji:controlStateタグを追加します。
<uji:form ...>
<uji:controlState />
...
</uji:form>
注意
サーバー側で二重処理を防止する場合、セションが開始されてから破棄されるまで有効です。セションが開始される前または破棄されたあとは機能が無効になります。
関連項目
UJIタグリファレンス