zoukankan      html  css  js  c++  java
  • 使用session防止表单进行重复提交

    我们都知道可以通过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。

  • 相关阅读:
    luogu P3398 仓鼠找sugar
    关于lca
    luogu P3374 【模板】树状数组 1
    [NOIp2013普及组]车站分级
    [HDU1598]find the most comfortable road
    [NOI2015]程序自动分析
    [USACO08DEC]Secret Message
    [洛谷3375]【模板】KMP字符串匹配
    [ZJOI2010]网络扩容
    [SCOI2007]修车
  • 原文地址:https://www.cnblogs.com/mmykdbc/p/9055304.html
Copyright © 2011-2022 走看看