フォームの2度押し防止
フォームの送信ボタンを1度押した後に、ブラウザの戻るボタンでフォームページに戻ってまた送信を押す、2重送信(と言うんだろうか…)はウェブアプリケーションではよくある問題だ。 Strutsではsynchronizing tokenを使って二重送信を防止する。
簡単な例で説明しよう。 まずアクションマッピングは次のようになる。
<action path="/contact"
type="app.actions.SetupContactAction"
scope="request">
<forward name="success" path="/contactForm.jsp" />
</action>
<action path="/contact/submit"
type="app.actions.ContactSubmitAction"
name="contactForm"
validate="true"
input="/contactForm.jsp"
scope="request">
<forward name="success" path="/contactConfirm.jsp" />
</action>
contactForm.jspを呼び出す前にSetupContactFormActionを呼び出し、セッションにTokenをおく。
public class SetupContactFormAction extends Action {
public ActionForward execute (...) {
saveToken(request);
return mapping.findForward("success");
}
}
そしてContactSubmitActionではTokenが有効かどうかをチェックし、結果に応じて処理する。
public class ContactSubmitAction extends Action {
public ActionForward execute (...) {
//Tokenが有効=フォームを送信
if(isTokenValid(request)) {
resetToken(request);
//ここでフォームの処理。
}
//2度押しの場合
else {
saveToken(request);
ActionMessages message = new ActionMessages();
message.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("message.contact.resubmit"));
saveMessages(request, message);
}
return mapping.findForward("success");
}
}
<logic:messagesPresent message="true">
<html:messages id="message" message="true">
<bean:write name="message" />
</html:messages>
</logic:messagesPresent>