服务器端使用Session来防止表单重复提交

2015-05-05  本文已影响1016人  wswenyue

解决思路:

具体的做法:

在服务器端生成一个唯一的随机标识号,专业术语称为Token(令牌),同时在当前用户的Session域中保存这个Token。然后将Token发送到客户端的Form表单中,在Form表单中使用隐藏域来存储这个Token,表单提交的时候连同这个Token一起提交到服务器端,然后在服务器端判断客户端提交上来的Token与服务器端生成的Token是否一致,如果不一致,那就是重复提交了,此时服务器端就可以不处理重复提交的表单。如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。

在下列情况下,服务器程序将拒绝处理用户提交的表单请求:


代码实现:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>form.html</title>
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">

    <script type="text/javascript">
        var isCommitted = false;
        function dosubmit()
        {
            if(isCommitted==false){
                isCommitted = true;
                return true;
            }else{
                return false;
            }
                
        }
        function dosubmit(){
            var submit = document.getElementById("submit");
            submit.disabled= "disabled";
            return true;
        
        }
    </script>


  </head> 
  <body>    
    <form action="~这里是你表单提交的servlet路径~/FormServlet" method="post" onsubmit="return dosubmit()">
        用户名:<input type="text" name="username">
        <input type="submit" value="提交" id="submit">
    </form>
  </body>
</html>

//负责产生表单
public class FormServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        
        String token = TokenProccessor.getInstance().makeToken();
        request.getSession().setAttribute("token", token);  //在服务器端保存随机数
        
        out.println("<form action='/day07/servlet/DoFormServlet' method='post'>");
            out.write("<input type='hidden' name='token' value='"+token+"'>");
            out.println("用户名:<input type='text' name='username'>");
            out.println("<input type='submit' value='提交'>");
        out.println("</form>");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);
    }
}
public class DoFormServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        
        boolean b = isToken(request);  //判断用户是否是重复提交
        if(b==true){
            System.out.println("请不要重复提交");
            return;
        }
        
        request.getSession().removeAttribute("token");//移除session中的token
        
        System.out.println("处理用户提交请求!!");
        
    }

  /**
         * 判断客户端提交上来的令牌和服务器端生成的令牌是否一致
         * @param request
         * @return 
         *         true 用户重复提交了表单 
         *         false 用户没有重复提交表单
         */

    private boolean isToken(HttpServletRequest request) {
        
        String client_token = request.getParameter("token");
        //1、如果用户提交的表单数据中没有token,则用户是重复提交了表单
        if(client_token==null){
            return true;
        }
        //取出存储在Session中的token
        String server_token = (String) request.getSession().getAttribute("token");
        //2、如果当前用户的Session中不存在Token(令牌),则用户是重复提交了表单
        if(server_token==null){
            return true;
        }
        //3、存储在Session中的Token(令牌)与表单提交的Token(令牌)不同,则用户是重复提交了表单
        if(!client_token.equals(server_token)){
            return true;
        }
        
        return false;
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);
    }

}
上一篇 下一篇

猜你喜欢

热点阅读