JSP入門之避免Form表單重復提交的幾種方案
對于JSP入門的初級的學習者表單的提交是一個非常困擾的問題,那么如何避免Form表單多次提交呢?可以從以下的幾個方面入手:
一.對于初學JSP可以先通過Javascript中設置
設置一個變量,只允許表單提交一次。
- ﹤script language="javascript"﹥
- var checkSubmitFlg = false;
- function checkSubmit() {
- if (checkSubmitFlg == true) {
- return false;
- }
- checkSubmitFlg = true;
- return true;
- }
- document.ondblclick = function docondblclick() {
- window.event.returnValue = false;
- }
- document.onclick = function doconclick() {
- if (checkSubmitFlg) {
- window.event.returnValue = false;
- }
- }
- ﹤/script﹥
- ﹤html:form action="myAction.do" method="post" onsubmit="return checkSubmit();"﹥
二. 對于JSP人門還要掌握Javascript的另一設置
將表單提交按鈕或者image置為disable
- ﹤html:form action="myAction.do" method="post"
- onsubmit="getElById('submitInput').disabled = true; return true;"﹥
- ﹤html:image styleId="submitInput" src="images/ok_b.gif" border="0" /﹥
- ﹤/html:form﹥
三.在JSP入門階段也要注意善于利用STRUTS的同步令牌機制
利用同步令牌(Token)機制來解決Web應用中重復Form表單提交的問題,Struts也給出了一個參考實現。
基本原理:
服務器端在處理到達的請求之前,會將請求中包含的令牌值與保存在當前用戶會話中的令牌值進行比較,看是否匹配。在處理完該請求后,且在答復發送給客戶端之前,將會產生一個新的令牌,該令牌除傳給客戶端以外,也會將用戶會話中保存的舊的令牌進行替換。這樣如果用戶回退到剛才的提交頁面并再次提交的話,客戶端傳過來的令牌就和服務器端的令牌不一致,從而有效地防止了重復提交的發生。
- if (isTokenValid(request, true)) {
- // your code here
- return mapping.findForward("success");
- } else {
- saveToken(request);
- return mapping.findForward("submitagain");
- }
STRUTS根據用戶會話ID和當前系統時間來生成一個唯一(對于每個會話)令牌的,具體實現可以參考TokenProcessor類中的generateToken()方法。
1. //驗證事務控制令牌,﹤html:form ﹥會自動根據session中標識生成一個隱含input代表令牌,防止兩次提交
2. 在action中:
- //﹤input type="hidden" name="org.apache.struts.taglib.html.TOKEN"
- // value="6aa35341f25184fd996c4c918255c3ae"﹥
- if (!isTokenValid(request))
- errors.add(ActionErrors.GLOBAL_ERROR,
- new ActionError("error.transaction.token"));
- resetToken(request); //刪除session中的令牌
3. action有這樣的一個方法生成令牌
- protected String generateToken(HttpServletRequest request) {
- HttpSession session = request.getSession();
- try {
- byte id[] = session.getId().getBytes();
- byte now[] =
- new Long(System.currentTimeMillis()).toString().getBytes();
- MessageDigest md = MessageDigest.getInstance("MD5");
- md.update(id);
- md.update(now);
- return (toHex(md.digest()));
- } catch (IllegalStateException e) {
- return (null);
- } catch (NoSuchAlgorithmException e) {
- return (null);
- }
- }
在更新的時候防止表單按鈕重復點擊,主要是用Session來做判斷
四.在JSP入門時還要掌握頁面方式
- ﹤input type="hidden " name=" ﹤% =com.lims.util.SynchroToken.TOKEN_NAME%﹥ " value =" ﹤%= com.lims.util.SynchroToken.getToken(request)%﹥" ﹥
- SynchroToken.java
- package com.lims.util;
- import org.apache.struts.util.*;
- import javax.servlet.http.*;
- import javax.servlet.jsp.*;
- import org.apache.struts.action.*;
- /**
- * ﹤p﹥Title: SynchroToken ﹤/p﹥
- * ﹤p﹥Description: ﹤/p﹥
- * ﹤p﹥Copyright: Copyright (c) 2004﹤/p﹥
- * ﹤p﹥Company: NetStar﹤/p﹥
- * @author Jstar
- * @version 1.0
- * Created in 2004/04/21
- */
- public class SynchroToken{
- public final static java.lang.String TOKEN_NAME = "_token";
- public static boolean checkToken (HttpServletRequest request){
- boolean isEqual = false;
- HttpSession session = request.getSession ();
- String formToken = request.getParameter (TOKEN_NAME);
- String sessionToken = (String)session.getAttribute (TOKEN_NAME);
- System.out.println ("formToken: " + formToken + " sessionToken: " +
- sessionToken);
- if (formToken != null && sessionToken == null){
- session.setAttribute (TOKEN_NAME, formToken);
- isEqual = true;
- }
- return isEqual;
- }
- /**
- * Insert the method's description here.
- * Creation date: (4/19/2004 3:23:25 PM)
- * @return java.lang.String
- * @param request javax.servlet.http.HttpServletRequest
- */
- public static String getToken (HttpServletRequest request){
- String token = "" + System.currentTimeMillis ();
- HttpSession session = request.getSession ();
- if (session != null){
- session.removeAttribute (TOKEN_NAME);
- }
- return token;z
- }
- /**
- * Insert the method's description here.
- * Creation date: (4/19/2004 3:24:10 PM)
- * @return java.lang.String
- */
- final static java.lang.String getTOKEN_NAME (){
- return TOKEN_NAME;
- }
- public static String message (PageContext pageContext, String key) throws
- JspException{
- return RequestUtils.message (pageContext, null, null, key);
- }
- }
五.也可以通過添加中轉頁面的方式
對于JSP入門的角度講,可以通過添加中轉頁面的方式,這樣做雖然在視覺上不是很好,頁面間顯繁瑣,但是這是有效地避免Form表單重復提交的好方式。
【編輯推薦】