防止重复提交demo

利用session防止重复提交

思路:

前端控制:在点击提交按钮后设置按钮不可用。

后台控制:利用session,在初次进入表单页面的时候前生成一个随机token,将token保存到session并返回到前端页面,前端提交页面,后台获取前端提交的token值与session中的token比较。

主要代码:

package servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import servlet.token.TokenProccessor;

public class FormServlet extends HttpServlet{

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 生成token
        String token = TokenProccessor.getInstance().makenToken();
        System.out.println("FormServlet中生成的token:" + token);
        
        req.getSession().setAttribute("token", token);
        // 进入表单提交页面
        req.getRequestDispatcher("/form.jsp").forward(req, resp);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

处理提交的Servlet

package servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DoFormServlet extends HttpServlet{

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        // 判断是否重复提交
        boolean b = isRepeatSubmit(req);
        
        if (true == b) {
            System.out.println("重复提交");
            return ;
        }
        
        req.getSession().removeAttribute("token");
        System.out.println("处理请求!");
        String userName = req.getParameter("username");
        try {
            // 模拟系统处理
            Thread.sleep(3*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("插入数据:"+userName);
    }
    
    private boolean isRepeatSubmit(HttpServletRequest req) {
        
        String client_token = req.getParameter("token");
        // 用户提交表单时不存在token 表示直接刷新页面重复提交
        if (client_token == null) {
            return true;
        }
        // 返回后再次提交,当前用户不存在token重复提交
        String server_token = (String) req.getSession().getAttribute("token");
        if(server_token==null){
            return true;
        }
        // Session中令牌与表单提交不一致 重复提交
        if (!client_token.equals(server_token)) {
            return true;
        }
        return false;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        this.doGet(req, resp);
    }
    
}

页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="${pageContext.request.contextPath }/DoFormServlet" method="post">
        <%-- <input type="hidden" name="token" value="<%=session.getAttribute("token")%>"> --%>
        用户名:<input type="text" name="username">
        <input type="hidden" name="token" value="${token }">
        <input type="submit" value="提交" id="submit">
    </form>
</body>

<script type="text/javascript">
    function doSubmit(){
        var btnSubmit = document.getElementById("submit");
        btnSubmit.disabled="disabled";
        return true;
    }
</script>
</html>

posted on 2018-07-12 15:29  无厘头的脑子  阅读(116)  评论(0编辑  收藏  举报