StrutsではWebアプリ開発時によくある問題として、「2度押し」を防ぐメソッドが用意されています。 「2度押し」は、例えばショッピングサイトで注文決定ボタンを押して、画面が切り替わる前に、もう1度注文決定を押ような場合ですね。
注文決定ボタンに対応するActionをOrderDesideAction、注文確定(保存)ボタンに対応するActionをOrderAcceptActionとします。この場合、以下のようなコーディングを行います。
?OrderDesideActionのexecute()にsaveTokenを記述。これによって同期Tokenが保存される。
※保存された同期Tokenはhtml:form のtaglibをレンダリングする際に自動的にhidden フィールドとしてフォームに挿入されます。。確認したい場合は、JSPのスクリプトレットに以下の記述をするとTokenを直に見ることが出来ます。
?OrderAcceptActionのexecute()にisTokenValidを記述。Returnがboolean==falseの場合、エラー処理。
ただこの方法には結構大きな1つの問題があります。
もうお分かりかと思いますが、2度押しの1回目は、isTokenValidの戻り値は必ずtrueの為、処理が継続されます。従って、エラー処理のメッセージに困るわけです。更に言うと処理結果の表示にも困りますね。
ただこれで2度押しの危険は避けられます。今回は2度押しはJavaScriptで排除し、isTokenValidはURLの直接指定(例:ブラウザのお気に入りからいきなり注文されたり)による処理排除に使用しました。
何かGoodな解決策を知っている方は是非是非私まで。
・org.apache.struts.Action#saveToken(HttpRequest request)
同期Tokenを保存する
・org.apache.struts.Action#isTokenValid(HttpRequest request,boolean)
同期Tokenを検証する
注文決定ボタンに対応するActionをOrderDesideAction、注文確定(保存)ボタンに対応するActionをOrderAcceptActionとします。この場合、以下のようなコーディングを行います。
?OrderDesideActionのexecute()にsaveTokenを記述。これによって同期Tokenが保存される。
※保存された同期Tokenはhtml:form のtaglibをレンダリングする際に自動的にhidden フィールドとしてフォームに挿入されます。。確認したい場合は、JSPのスクリプトレットに以下の記述をするとTokenを直に見ることが出来ます。
session.getAttribute(org.apache.struts.action.Action.TRANSACTION_TOKEN_KEY)
*同期Tokenはシステム時間(HEXかな?)を元に生成されるようです。
?OrderAcceptActionのexecute()にisTokenValidを記述。Returnがboolean==falseの場合、エラー処理。
ただこの方法には結構大きな1つの問題があります。
もうお分かりかと思いますが、2度押しの1回目は、isTokenValidの戻り値は必ずtrueの為、処理が継続されます。従って、エラー処理のメッセージに困るわけです。更に言うと処理結果の表示にも困りますね。
ただこれで2度押しの危険は避けられます。今回は2度押しはJavaScriptで排除し、isTokenValidはURLの直接指定(例:ブラウザのお気に入りからいきなり注文されたり)による処理排除に使用しました。
何かGoodな解決策を知っている方は是非是非私まで。
コメント