表单提交到servlet后,服务器端跳转后,刷新页面重复提交数据,怎么办?

解决方案 »

  1.   

    Servlet 防止刷新重复提交在java web工程中,当jsp向Servlet提交请求时,如何防止刷新提交(F5)?         第一种解决方法,参照老紫竹的思路:         可以使用的方法有,在jsp中定义一个变量值,这个变量值应该是唯一的,可以使用算法来保证生成数据的唯一性,例如hash算法,或者生成一个随机数(Random),并将这个数值保存到一个Set中,并将Set保存在session中,提交Servlet时将这个参数传递过去,在Servlet中的处理:接到参数和session中的set后,判断set中有没有传来的参数值,如果没有则页面是刷新造成的,并不是来自页面的提交,这时不做 insert data的处理。         jsp 代码 :         <%
            //生成一个formhash,算法可以自己定,不随便重复就可以了
            Random ran = new Random();
            String formhash = String.valueOf(ran.nextInt());
            //读取当前session里面的hashCode集合,此处使用了Set,方便判断。
            Set<String> formhashSession = (Set<String>) session.getAttribute("formhashSession");
            if (formhashSession == null) {
                 formhashSession = new HashSet<String>();
            }
            // 检测重复问题
            while (formhashSession.contains(formhash)) {
                 formhash = String.valueOf(ran.nextInt());
            }
            // 保存到session里面
            formhashSession.add(formhash);
            // 保存
            session.setAttribute("formhashSession", formhashSession);
         %>    <form>中增加:<input type="hidden" name="formhash" id="formhash" value="<%=formhash%>" />            Servlet代码:         // 拿到表单的formhash
             String formhash = request.getParameter("formhash");
             // 拿到session里面的集合
             Set<String> formhashSession = (Set<String>) session.getAttribute("formhashSession");
              // 如果没有,则是重复提交,或者非法提交
              if (formhashSession == null || !formhashSession.contains(formhash)) {
                    System.out.println("重复提交!");
               }else{                 //正常的操作           }           // 最后,如果操作成功,从session里面把这个formhash 删掉!
               formhashSession.remove(formhash);
               session.setAttribute("formhashSession", formhashSession);参考文章:http://blog.csdn.net/java2000_net/archive/2008/02/25/2119298.aspx          第二种解决方法, 参考struts的token(令牌)机制:          在提交的时候在Servlet中根据用户的sessionid和当前时间的long值生成一个令牌(每次提交都会生成一个新令牌),将令牌保存在该用户的会话中,并将令牌的值以request属性形式传到前端页面,在前端页面的form中增加传递令牌的隐藏域<input type="hidden" name="clientToken" value="<%=clientToken%>" />,提交form的时候,也会将clientToken传入Servlet,如果session中保存的令牌值与传入的不同,则是重复提交,因为每次请求Servlet都会生成新的令牌,刷新时的令牌值是旧的令牌值,不是最新的令牌值。           jsp代码:           <%
        String clientToken = (String)request.getAttribute("clientToken");
        clientToken = clientToken==null?"":clientToken;
               %><form>中增加<input type="hidden" name="clientToken" value="<%=clientToken%>" />          Servlet代码:          String clientToken = request.getParameter("clientToken");
              String sessionToken = (String) session.getAttribute("token");          if(sessionToken!=null&&!clientToken.equals(sessionToken)){
                     System.out.println("请不要重复提交!");
              }else{                  //正常的操作          }           //生成新令牌
               String token = generateToken(request);
               request.setAttribute("clientToken", token);
               //替换旧令牌
               session.setAttribute("token", token);参考文献:http://www.blogjava.net/yrJavaWorld/archive/2007/10/09/50020.html
      

  2.   

    1.使用页面跳转(response.sendRedirect("...jsp")的客户端跳转,还有服务器端跳转貌似也可以))
    2.使用Struts2里面的token拦截器
      

  3.   

    1L很详细啊,token比较简单,只要配置一下就行
      

  4.   

    out.println("<script type='text/javascript'>location.replace('other.jsp');</script>");
    换用客户端 js 重定向, location.replace 会替换浏览器的访问记录,刷新不会导致重复提交。
    缺点:多发一次请求和响应-----------------------如果非得使用服务端的 请求转发, 则只能使用上面高手所说的 令牌机制了
      

  5.   

    如果不是大内容提交的话,就用ajax提交吧。 最简单的方法了。
      

  6.   

    路上都是正解  令牌(token)机制