1. 程式人生 > >使用session防止表單進行重復提交

使用session防止表單進行重復提交

dig exc ati ges nproc 其他 延遲 odi 網絡

我們都知道可以通過js的方法來實現防止表單重復提交,但是js只適用於“在網絡延遲的情況下讓用戶有時間點擊多次submit按鈕導致表單重復提交” 的情況下進行操作,

那如果碰到“表單提交後用戶點擊【刷新】按鈕導致表單重復提交”和“用戶提交表單後,點擊瀏覽器的【後退】按鈕回退到表單頁面後進行再次提交”的場景下JS就顯得心有余而力不足了,這個時候我們可以通過java當中生成token驗證token來實現防止表單提交;

先看一下我的項目結構:

技術分享圖片

我們用到的只有這四個頁面,其他的可以忽略

首先先來看一下創建token的servlet,tokenDemo.java:

package session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "TokenDemo",urlPatterns = {"/session/TokenDemo"})
public class TokenDemo extends HttpServlet {
    private static final long serialVersionUID =  -884689940866074733L;
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String token = TokenProccessor .getInstance().makeToken();//創建令牌
//        System.out.print("生成的令牌token是"+token);
        request.getSession().setAttribute("token",token); //存到session裏面
        request.getRequestDispatcher("/token.jsp").forward(request,response);
    }
}

  這裏面有一個生成token的類,叫做TokenProccessor,接下來我們看看token是怎麽生成的,

TokenProccessor .java:
package session;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

import sun.misc.BASE64Encoder;

public class TokenProccessor {
    private TokenProccessor() {}

    ;
    private static final TokenProccessor instance = new TokenProccessor();

    public static TokenProccessor getInstance() {
        return instance;
    }

    //生成token
    public String makeToken(){
        String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
        try{
            MessageDigest md = MessageDigest.getInstance("md5");
            byte md5[] = md.digest(token.getBytes());
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(md5);
        }catch(NoSuchAlgorithmException e){
            throw new RuntimeException(e);
        }
    }

}

  好,我們現在有了token,我們可以在頁面上去使用它:token.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>token</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/session/ResultToken" method="post">
    <%--使用隱藏存儲生成token--%>

    <input type="hidden" name="token" value="${token}">
    用戶名:<input type="text" name="username">
    <input type="submit" value="提交">

</form>

</body>
</html>

  我們接下來應該幹嘛呢,對,當然是要進行表單的驗證啦,resultToken.java:

package session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ResultToken", urlPatterns = {"/session/ResultToken"})
public class ResultToken extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");
        boolean b = isRepeatSubmit(request); //判斷用戶是否重復提交;
        if (b == true) {
            response.getWriter().println("請不要重復提交");
            return;
        }
        request.getSession().removeAttribute("token");
        response.getWriter().println("處理用戶提交請求");
    }

    /***
     * 判斷用戶提交上來的token和服務器生成的token是否一致
     * true:重復提交了
     *false:沒有重復提交
     * */
    private boolean isRepeatSubmit(HttpServletRequest request) {
        String client_token = request.getParameter("token");
        //如果用戶提交的沒有token,那麽用戶則是重復提交了表單
        if (client_token == null) {
            return true;
        }
        //取出session中的token
        String server_token = (String) request.getSession().getAttribute("token");
        //如果哦用戶的session裏面不存在Token,則用戶重復提交了表單
        if (server_token.equals(client_token)) {
            return true;
        }
        return false;
    }
}

  ok,記得寫完servlet的時候必須要去web.xml配置一下,不然取不到路徑。所有的登錄都需要來驗證token。

使用session防止表單進行重復提交