web開發解決頁面重複提交問題

1、手機端應用和web開發相似的問題

以前作安卓或蘋果手機應用開發時,好比發帖子,點發布按鈕後時,咱們每每會作一些操做,好比按鈕變灰,而後增長一個轉圈加載的遮罩,主要是爲了防止用戶快速點擊形成屢次提交數據。java

web開發時也會有相似的問題。增長、修改、刪除這些處理業務的操做也會有形成屢次提交數據的問題。web

一、場景一(屢次點擊按鈕提交表單)

若是網速比較慢的狀況下,用戶提交表單後,發現服務器半天都沒有響應,那麼用戶可能會覺得是本身沒有提交表單,就會再點擊提交按鈕重複提交表單。面對這個狀況,若是隻是在jsp頁面,加上js判斷的代碼瀏覽器

var checkSubmitFlg = false;服務器

 function check(){session

     if (checkSubmitFlg == true){dom

            alert("重複提交");jsp

            return;編碼

       }else{spa

    checkSubmitFlg = true;   .net

    myform.submit();

     }

 }

JavaScript是能夠解決這個問題的,固然還能夠"用JavaScript控制Form表單只能提交一次"。只是點提交按鈕後讓按鈕變灰相似手機端的作法。可是這種作法針對如下2,3場景確不行。

二、場景二 (點刷新)    場景三(點後退)

場景二表單提交後用戶點擊【刷新】按鈕致使表單重複提交 和 場景三用戶提交表單後,點擊瀏覽器的【後退】按鈕回退到表單頁面後進行再次提交,用戶這樣的操做爲了解決重複提交表單的問題,咱們能夠在服務端利用session去解決。

具體的作法:在服務器端生成一個惟一的隨機標識號,專業術語稱爲Token(令牌),同時在當前用戶的Session域中保存這個Token。而後將Token發送到客戶端的Form表單中,在Form表單中使用隱藏域來存儲這個Token,表單提交的時候連同這個Token一塊兒提交到服務器端,而後在服務器端判斷客戶端提交上來的Token與服務器端生成的Token是否一致,若是不一致,那就是重複提交了,此時服務器端就能夠不處理重複提交的表單。若是相同則處理表單提交,處理完後清除當前用戶的Session域中存儲的標識號。
  在下列狀況下,服務器程序將拒絕處理用戶提交的表單請求:

  1. 存儲Session域中的Token(令牌)與表單提交的Token(令牌)不一樣。
  2. 當前用戶的Session中不存在Token(令牌)
  3. 用戶提交的表單數據中沒有Token(令牌)

三、代碼

封裝了一個類TokenProcessor  代碼以下

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import sun.misc.BASE64Encoder;

/**
 * 類說明:令牌    防止刷新或程序打斷點或快速點擊 重複提交
 * @author wangbx
 * @date 2016年11月2日 下午2:41:34
 */
public class TokenProcessor {
    private static final TokenProcessor instance = new TokenProcessor();
    private TokenProcessor(){}
    public static TokenProcessor getInstance(){
        return instance;
    }
    public String generateToken(){
        String token = System.currentTimeMillis()+new Random().nextInt()+"";
        try{
            MessageDigest md = MessageDigest.getInstance("md5");
            byte[] md5 = md.digest(token.getBytes());
            //base64編碼
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(md5);
        }catch(NoSuchAlgorithmException e){
            e.printStackTrace(); 
            throw new RuntimeException(e);
        }
    }
    /**
     * 功能描述:判斷session中token是否失效   true:沒有失效
     * @author wangbx
     * @date 2016年11月2日 下午4:04:23
     * @param @param request
     * @param @return 
     * @return boolean
     */
    public synchronized  boolean isTokenValid(HttpServletRequest request) {
        String client_token=request.getParameter("token");
        if(client_token==null)
        {
          return false;
        }
        String server_token=(String)request.getSession().getAttribute("token");
        if(server_token==null)
        {
          return false;
        }
        if(!client_token.equals(server_token))
        {
          return false;
        }
        return true;
      }
    
    /**
     * 功能描述:爲請求新建一個token標記,並把字符值存入session中
     * @author wangbx
     * @date 2016年11月2日 下午4:16:41
     * @param @param request 
     * @return void
     */
     public synchronized void saveToken(HttpServletRequest request){
        HttpSession session = request.getSession(true);
        TokenProcessor tp=TokenProcessor.getInstance();
        String token=tp.generateToken();
        session.setAttribute("token", token);
     }
     
     /**
      * 功能描述: 從新設置token,當頁面被請求後,將session中的token屬性去除
      * @author wangbx
      * @date 2016年11月2日 下午4:20:38
      * @param @param request 
      * @return void
      */
     public synchronized void resetToken(HttpServletRequest request){
         HttpSession session = request.getSession(false);
         if(session != null){
             session.removeAttribute("token");
         }
     }
    
}
 

針對開發人員的全部模塊  須要在三處複製下代碼

1、jsp界面的form表單裏 加一個隱藏文本框

 2、跳到發佈的界面或修改界面前的方法裏 要添加兩行代

3、在具體提交方法加上下面代碼

OK  

相關文章
相關標籤/搜索