精华内容
下载资源
问答
  • 解决jsp表单重复提交问题

    千次阅读 2015-03-11 23:59:44
    方法一:利用同步令牌(Token)机制来解决Web应用中重复提交的问题   这种做法只能是解决问题的一种做法,...Struts的Token(令牌)机制能够很好的解决表单重复提交的问题,基本原理是:服务器端在处理到达的请求之

    方法一:利用同步令牌(Token)机制来解决Web应用中重复提交的问题

     

    这种做法只能是解决问题的一种做法,不过在大型项目中不可能用这种做法,此种做法不能根本解决问题,可以通过重写URL跳过JS校验一样提前到后台去。
    一般项目中都是用令牌机制处理这个问题(struts为例)

    Struts
    Token(令牌)机制能够很好的解决表单重复提交的问题,基本原理是:服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。

      这时其实也就是两点,第一:你需要在请求中有这个令牌值,请求中的令牌值如何保存,其实就和我们平时在页面中保存一些信息是一样的,通过隐藏字段来保存,保存的形式如:input type="hidden"name="org.apache.struts.taglib.html.TOKEN"value="6aa35341f25184fd996c4c918255c3ae"〉,这个valueTokenProcessor类中的generateToken()获得的,是根据当前用户的session id和当前时间的long值来计算的。第二:在客户端提交后,我们要根据判断在请求中包含的值是否和服务器的令牌一致,因为服务器每次提交都会生成新的 Token,所以,如果是重复提交,客户端的Token值和服务器端的Token值就会不一致。下面就以在数据库中插入一条数据来说明如何防止重复提交。

    struts1
    点麻烦,故此处不提供用例。
    struts2
    就做得很好,只要是<s:form></s:form>这间加上<s:token/>就可以自动完成重复提交(原理同上

     

     

    方法二:js

    http://www.ibeifeng.com/bbs/read-htm-tid-13978.html

     

    我提供一个简单的方案用JavaScript解决
    在表单中写一个隐藏域<input   type="hidden"  value="false"   name="resubmit "/>   
    如果第一次提交,就改变value="true"   ;   
    再次提交时候,可以用JS 在客户端判断hidde  
       
     
    var   resubmit =  false;   
    function   checkCFSubmit()   
    {   
            if  (resubmit )   
            {   
             return   false;   
            }   
            else   
            {   
              resubmit=   true;   
             return   true;   
    }   

    然后在<form>中添加οnsubmit="javascript:return  checkCFSubmit();"

     

     

     

     

    问题1

    CSS样式单的基本应用

     

    问题2

    Dojo的使用,实现动态效果,jar包的引入

     

     

    问题3

     

    显示时间的js组件,下载使用

     

     

    问题以及菜单如何实现层级显示,是属于html标签吗,还是属于表单(有序表单、无序表单)

     

     

    问题5  HTML5

     

     

    问题6  XML

     

     

    问题7  Spring的思想

     

     

    问题8 Hibernate的事务控制

     

     

    问题9 访问权限控制实现,开发一个小模块,测试一下。

     

     

    问题10  安装oracle  找到我的留言板项目,实现BBS 分页,昵称,头像,按照关键词搜索???(搜索引擎有没有现有的开源组件直接借鉴使用,按照用户名搜索用户的留言,管理自己的留言,回复功能。。。。)

    展开全文
  • 主要介绍了JSP使用自定义标签防止表单重复提交的方法,以实例形式较为详细的分析了JSP基于自定义标签防止表单重复提交的具体步骤与实现方法,具有一定参考借鉴价值,需要的朋友可以参考下
  • 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。 一、表单重复...

    在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。

    一、表单重复提交的常见应用场景

    有如下的form.jsp页面

    复制代码
     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 <!DOCTYPE HTML>
     3 <html>
     4   <head>
     5     <title>Form表单</title>
     6   </head>
     7   
     8   <body>
     9       <form action="${pageContext.request.contextPath}/servlet/DoFormServlet" method="post">
    10         用户名:<input type="text" name="username">
    11         <input type="submit" value="提交" id="submit">
    12     </form>
    13   </body>
    14 </html>
    复制代码

      form表单提交到DoFormServlet进行处理

    复制代码
     1 package xdp.gacl.session;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.ServletException;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 
     9 public class DoFormServlet extends HttpServlet {
    10 
    11     public void doGet(HttpServletRequest request, HttpServletResponse response)
    12             throws ServletException, IOException {
    13         //客户端是以UTF-8编码传输数据到服务器端的,所以需要设置服务器端以UTF-8的编码进行接收,否则对于中文数据就会产生乱码
    14         request.setCharacterEncoding("UTF-8");
    15         String userName = request.getParameter("username");
    16         try {
    17             //让当前的线程睡眠3秒钟,模拟网络延迟而导致表单重复提交的现象
    18             Thread.sleep(3*1000);
    19         } catch (InterruptedException e) {
    20             e.printStackTrace();
    21         }
    22         System.out.println("向数据库中插入数据:"+userName);
    23     }
    24 
    25     public void doPost(HttpServletRequest request, HttpServletResponse response)
    26             throws ServletException, IOException {
    27         doGet(request, response);
    28     }
    29 
    30 }
    复制代码

      如果没有进行form表单重复提交处理,那么在网络延迟的情况下下面的操作将会导致form表单重复提交多次

    1.1、场景一:在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交

      演示动画如下所示:

     1.2、场景二:表单提交后用户点击【刷新】按钮导致表单重复提交

    演示动画如下所示:

      点击浏览器的刷新按钮,就是把浏览器上次做的事情再做一次,因为这样也会导致表单重复提交。

    1.3、场景三:用户提交表单后,点击浏览器的【后退】按钮回退到表单页面后进行再次提交

    演示动画如下所示:

    二、利用JavaScript防止表单重复提交

      既然存在上述所说的表单重复提交问题,那么我们就要想办法解决,比较常用的方法是采用JavaScript来防止表单重复提交,具体做法如下:

    修改form.jsp页面,添加如下的JavaScript代码来防止表单重复提交

    复制代码
     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 <!DOCTYPE HTML>
     3 <html>
     4   <head>
     5     <title>Form表单</title>
     6         <script type="text/javascript">
     7         var isCommitted = false;//表单是否已经提交标识,默认为false
     8         function dosubmit(){
     9             if(isCommitted==false){
    10                 isCommitted = true;//提交表单后,将表单是否已经提交标识设置为true
    11                 return true;//返回true让表单正常提交
    12             }else{
    13                 return false;//返回false那么表单将不提交
    14             }
    15         }
    16     </script>
    17   </head>
    18   
    19   <body>
    20       <form action="${pageContext.request.contextPath}/servlet/DoFormServlet" onsubmit="return dosubmit()" method="post">
    21         用户名:<input type="text" name="username">
    22         <input type="submit" value="提交" id="submit">
    23     </form>
    24   </body>
    25 </html>
    复制代码

      我们看看使用了JavaScript来防止表单提交重复是否可以成功,运行效果如下:

      可以看到,针对"在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交"这个应用场景,使用JavaScript是可以解决这个问题的,解决的做法就是"用JavaScript控制Form表单只能提交一次"。

      除了用这种方式之外,经常见的另一种方式就是表单提交之后,将提交按钮设置为不可用,让用户没有机会点击第二次提交按钮,代码如下:

    复制代码
    1 function dosubmit(){
    2     //获取表单提交按钮
    3     var btnSubmit = document.getElementById("submit");
    4     //将表单提交按钮设置为不可用,这样就可以避免用户再次点击提交按钮
    5     btnSubmit.disabled= "disabled";
    6     //返回true让表单可以正常提交
    7     return true;
    8 }
    复制代码

    运行效果如下:

       另外还有一种做法就是提交表单后,将提交按钮隐藏起来,这种做法和将提交按钮设置为不可用是差不多的,个人觉得将提交按钮隐藏影响到页面布局的美观,并且可能会让用户误以为是bug(怎么我一点击按钮,按钮就不见了呢?用户可能会有这样的疑问),我个人在开发中用得比较多的是表单提交后,将提交按钮设置为不可用,反正使用JavaScript防止表单重复提交的做法都是差不多的,目的都是让表单只能提交一次,这样就可以做到表单不重复提交了。

      使用JavaScript防止表单重复提交的做法只对上述提交到导致表单重复提交的三种场景中的【场景一】有效,而对于【场景二】和【场景三】是没有用,依然无法解决表单重复提交问题。

    三、利用Session防止表单重复提交

      对于【场景二】和【场景三】导致表单重复提交的问题,既然客户端无法解决,那么就在服务器端解决,在服务器端解决就需要用到session了。

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

    1. 存储Session域中的Token(令牌)与表单提交的Token(令牌)不同。
    2. 当前用户的Session中不存在Token(令牌)
    3. 用户提交的表单数据中没有Token(令牌)

    看具体的范例:

      1.创建FormServlet,用于生成Token(令牌)和跳转到form.jsp页面

    复制代码
     1 package xdp.gacl.session;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.ServletException;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 
     9 public class FormServlet extends HttpServlet {
    10     private static final long serialVersionUID = -884689940866074733L;
    11 
    12     public void doGet(HttpServletRequest request, HttpServletResponse response)
    13             throws ServletException, IOException {
    14 
    15         String token = TokenProccessor.getInstance().makeToken();//创建令牌
    16         System.out.println("在FormServlet中生成的token:"+token);
    17         request.getSession().setAttribute("token", token);  //在服务器使用session保存token(令牌)
    18         request.getRequestDispatcher("/form.jsp").forward(request, response);//跳转到form.jsp页面
    19     }
    20 
    21     public void doPost(HttpServletRequest request, HttpServletResponse response)
    22             throws ServletException, IOException {
    23         doGet(request, response);
    24     }
    25 
    26 }
    复制代码

      2.在form.jsp中使用隐藏域来存储Token(令牌)

    复制代码
     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     3 <html>
     4 <head>
     5 <title>form表单</title>
     6 </head>
     7 
     8 <body>
     9     <form action="${pageContext.request.contextPath}/servlet/DoFormServlet" method="post">
    10         <%--使用隐藏域存储生成的token--%>
    11         <%--
    12             <input type="hidden" name="token" value="<%=session.getAttribute("token") %>">
    13         --%>
    14         <%--使用EL表达式取出存储在session中的token--%>
    15         <input type="hidden" name="token" value="${token}"/> 
    16         用户名:<input type="text" name="username"> 
    17         <input type="submit" value="提交">
    18     </form>
    19 </body>
    20 </html>
    复制代码

      3.DoFormServlet处理表单提交

    复制代码
     1 package xdp.gacl.session;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.ServletException;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 
     9 public class DoFormServlet extends HttpServlet {
    10 
    11     public void doGet(HttpServletRequest request, HttpServletResponse response)
    12                 throws ServletException, IOException {
    13 
    14             boolean b = isRepeatSubmit(request);//判断用户是否是重复提交
    15             if(b==true){
    16                 System.out.println("请不要重复提交");
    17                 return;
    18             }
    19             request.getSession().removeAttribute("token");//移除session中的token
    20             System.out.println("处理用户提交请求!!");
    21         }
    22         
    23         /**
    24          * 判断客户端提交上来的令牌和服务器端生成的令牌是否一致
    25          * @param request
    26          * @return 
    27          *         true 用户重复提交了表单 
    28          *         false 用户没有重复提交表单
    29          */
    30         private boolean isRepeatSubmit(HttpServletRequest request) {
    31             String client_token = request.getParameter("token");
    32             //1、如果用户提交的表单数据中没有token,则用户是重复提交了表单
    33             if(client_token==null){
    34                 return true;
    35             }
    36             //取出存储在Session中的token
    37             String server_token = (String) request.getSession().getAttribute("token");
    38             //2、如果当前用户的Session中不存在Token(令牌),则用户是重复提交了表单
    39             if(server_token==null){
    40                 return true;
    41             }
    42             //3、存储在Session中的Token(令牌)与表单提交的Token(令牌)不同,则用户是重复提交了表单
    43             if(!client_token.equals(server_token)){
    44                 return true;
    45             }
    46             
    47             return false;
    48         }
    49 
    50     public void doPost(HttpServletRequest request, HttpServletResponse response)
    51             throws ServletException, IOException {
    52         doGet(request, response);
    53     }
    54 
    55 }
    复制代码

      生成Token的工具类TokenProccessor

    复制代码
     1 package xdp.gacl.session;
     2 
     3 import java.security.MessageDigest;
     4 import java.security.NoSuchAlgorithmException;
     5 import java.util.Random;
     6 import sun.misc.BASE64Encoder;
     7 
     8 public class TokenProccessor {
     9 
    10     /*
    11      *单例设计模式(保证类的对象在内存中只有一个)
    12      *1、把类的构造函数私有
    13      *2、自己创建一个类的对象
    14      *3、对外提供一个公共的方法,返回类的对象
    15      */
    16     private TokenProccessor(){}
    17     
    18     private static final TokenProccessor instance = new TokenProccessor();
    19     
    20     /**
    21      * 返回类的对象
    22      * @return
    23      */
    24     public static TokenProccessor getInstance(){
    25         return instance;
    26     }
    27     
    28     /**
    29      * 生成Token
    30      * Token:Nv6RRuGEVvmGjB+jimI/gw==
    31      * @return
    32      */
    33     public String makeToken(){  //checkException
    34         //  7346734837483  834u938493493849384  43434384
    35         String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
    36         //数据指纹   128位长   16个字节  md5
    37         try {
    38             MessageDigest md = MessageDigest.getInstance("md5");
    39             byte md5[] =  md.digest(token.getBytes());
    40             //base64编码--任意二进制编码明文字符   adfsdfsdfsf
    41             BASE64Encoder encoder = new BASE64Encoder();
    42             return encoder.encode(md5);
    43         } catch (NoSuchAlgorithmException e) {
    44             throw new RuntimeException(e);
    45         }
    46     }
    47 }
    复制代码

      首先访问FormServlet,在FormServlet中生成Token之后再重定向到form.jsp页面,这次是在服务器端处理表单重复提交的,运行效果如下:

      从运行效果中可以看到,通过这种方式处理表单重复提交,可以解决上述的场景二和场景三中出现的表单重复提交问题。


    转自:http://www.cnblogs.com/xdp-gacl/p/3859416.html

    展开全文
  • 1.什么叫表单重复提交:  所谓表单重复提交,是指用户通过多次点击提交按钮或多次刷新表单提交页面等造成用户表单重复提交的现象 2.表单重复提交有哪些情况:  (1)用户在程序提交表单的时间段里多次提交表单  (2)...

    1.什么叫表单重复提交:

         所谓表单重复提交,是指用户通过多次点击提交按钮或多次刷新表单提交页面等造成用户表单重复提交的现象

    2.表单重复提交有哪些情况:

         (1)用户在程序提交表单的时间段里多次提交表单
         (2)重复刷新提交后的表单
         (3)用户点击浏览器回退按钮,然后再次提交

    3.如果解决表单重复提交:

        (1)方法1:客户端防表单重复提交:  一般通过js代码防止第一种情况的发生,对于第二种和第三种的情况很难避免,并且稍微有经验的用户可以通过去掉页面js生成自己的html页面来访问服务器,这样客户端的防表单重复提交只能“防君子不能防小人”,并且可以增强用户体验感。


         (2)方法2:服务器端session防表单重复提交:一般是利用令牌的原理来实现表单重复提交的,具体做法:

               A. 对于用户每一次访问表单页面,均先经过CreateFormServlet的Servlet,其作用是在跳转表单页面之前,由BASE64Encoder类生成一个唯一的字符串,即表单号,并保存在session域中.

               B.然后用户提交表单时,带着表单号,先验证客户端提交过来的表单号和session域中的表单号是否相同,如果不同则证明是重复提交,如果相同,则证明是第一次提交,并将表单号从session域中移除。

    4.例子程序:

    regist.jsp

    1. <%@ page language="java"import="java.util.*"pageEncoding="utf-8"%> 
    2.  
    3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
    4. <html> 
    5. <scripttype="text/javascript"> 
    6.     /*虽然客户端防表单重复提交,有很多漏洞,但是为了提高客户体验感,一把是客户端和服务器配合防表单重复提交, 
    7.               客户端防重复提交的漏洞:1.客户复制源代码,去掉此js脚本,生成自己的html页面,然后提交 
    8.                            2.重复刷新提交后的表单 
    9.                            3.用户点击浏览器回退按钮,然后再次提交 
    10.       
    11.              客户端防重复提交的代码: 
    12.        1.方法1: 
    13.          var isCommited =false
    14.          function dosubmit(){ 
    15.             if(!isCommited){ 
    16.                 isCommited = true
    17.                 return true; 
    18.             }else{ 
    19.                 return false; 
    20.             } 
    21.          } 
    22.      */ 
    23.       
    24.      //或者使"注册"按钮点击一次后不可用 
    25.          function dosubmit1(){ 
    26.             var input = document.getElementById("submit"); 
    27.             input.disabled="disabled"
    28.             return true; 
    29.          } 
    30.   </script> 
    31.   <body> 
    32.          <formaction="/CookieAndSession/servlet/regist"method="post"onsubmit="return dosubmit()"> 
    33.              用户名:<inputtype="text"name="username"value="aaa"><br/> 
    34.              <inputtype="hidden"name="c_token"value="${token}"> 
    35.              <inputid="submit"type="submit"value="注册"> 
    36.          </form> 
    37.    </body> 
    38. </html> 
    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
     <script type="text/javascript">
        /*虽然客户端防表单重复提交,有很多漏洞,但是为了提高客户体验感,一把是客户端和服务器配合防表单重复提交,
                  客户端防重复提交的漏洞:1.客户复制源代码,去掉此js脚本,生成自己的html页面,然后提交
                               2.重复刷新提交后的表单
                               3.用户点击浏览器回退按钮,然后再次提交
         
                 客户端防重复提交的代码:
           1.方法1:
    	     var isCommited = false;
    	     function dosubmit(){
    	        if(!isCommited){
    	            isCommited = true;
    	            return true;
    	        }else{
    	            return false;
    	        }
    	     }
         */
         
         //或者使"注册"按钮点击一次后不可用
    	     function dosubmit1(){
    	        var input = document.getElementById("submit");
    	        input.disabled="disabled";
    	        return true;
    	     }
      </script>
      <body>
             <form action="/CookieAndSession/servlet/regist" method="post" οnsubmit="return dosubmit()">
                 用户名:<input type="text" name="username" value="aaa"><br/>
                 <input type="hidden" name="c_token" value="${token}">
                 <input id="submit" type="submit" value="注册" >
             </form>
       </body>
    </html>
    
    CreateFormServlet.java     url-pattern:  /servlet/createform

    1. package edu.form; 
    2.  
    3. import java.io.IOException; 
    4. import java.security.MessageDigest; 
    5. import java.security.NoSuchAlgorithmException; 
    6. import java.util.Random; 
    7. import javax.servlet.ServletException; 
    8. import javax.servlet.http.HttpServlet; 
    9. import javax.servlet.http.HttpServletRequest; 
    10. import javax.servlet.http.HttpServletResponse; 
    11. import sun.misc.BASE64Encoder; 
    12.  
    13. public class CreateFormServletextends HttpServlet { 
    14.  
    15.     public void doGet(HttpServletRequest request, HttpServletResponse response) 
    16.             throws ServletException, IOException { 
    17.         //产生表单号 
    18.         String token = TokenProcessor.getInstance().generateToken(); 
    19.         request.getSession().setAttribute("token", token); 
    20.         request.getRequestDispatcher("/regist.jsp").forward(request, response); 
    21.     } 
    22.  
    23.     public void doPost(HttpServletRequest request, HttpServletResponse response) 
    24.             throws ServletException, IOException { 
    25.          doGet(request, response); 
    26.     } 
    27.      
    28. class TokenProcessor{ 
    29.     private static TokenProcessor token =new TokenProcessor(); 
    30.     private TokenProcessor(){} 
    31.     public static TokenProcessor getInstance(){ 
    32.         return token; 
    33.     } 
    34.     public String generateToken(){ 
    35.         String token = System.currentTimeMillis()+new Random().nextInt()+""
    36.         try
    37.             MessageDigest md = MessageDigest.getInstance("md5"); 
    38.             byte[] md5 = md.digest(token.getBytes()); 
    39.             //base64编码 
    40.             BASE64Encoder encoder = new BASE64Encoder(); 
    41.             return encoder.encode(md5); 
    42.         } catch (NoSuchAlgorithmException e) { 
    43.             throw new RuntimeException(e); 
    44.         } 
    45.     } 
    46.      
    package edu.form;
    
    import java.io.IOException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Random;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import sun.misc.BASE64Encoder;
    
    public class CreateFormServlet extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
            //产生表单号
    		String token = TokenProcessor.getInstance().generateToken();
    		request.getSession().setAttribute("token", token);
    		request.getRequestDispatcher("/regist.jsp").forward(request, response);
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
             doGet(request, response);
    	}
    	
    }
    class TokenProcessor{
    	private static TokenProcessor token = new TokenProcessor();
    	private TokenProcessor(){}
    	public static TokenProcessor getInstance(){
    		return token;
    	}
    	public String generateToken(){
    		String token = System.currentTimeMillis()+new Random().nextInt()+"";
    		try {
    			MessageDigest md = MessageDigest.getInstance("md5");
    			byte[] md5 = md.digest(token.getBytes());
    			//base64编码
    			BASE64Encoder encoder = new BASE64Encoder();
    			return encoder.encode(md5);
    		} catch (NoSuchAlgorithmException e) {
    			throw new RuntimeException(e);
    		}
    	}
    	
    }
    
    RegistServlet.java     url-pattern:  /servlet/regist
    1. package edu.form; 
    2.  
    3. import java.io.IOException; 
    4. import java.io.PrintWriter; 
    5. import javax.servlet.ServletException; 
    6. import javax.servlet.http.HttpServlet; 
    7. import javax.servlet.http.HttpServletRequest; 
    8. import javax.servlet.http.HttpServletResponse; 
    9. public class RegistServletextends HttpServlet { 
    10.  
    11.     public void doGet(HttpServletRequest request, HttpServletResponse response) 
    12.             throws ServletException, IOException { 
    13.         response.setCharacterEncoding("utf-8"); 
    14.         response.setContentType("text/html;charset=utf-8"); 
    15.         PrintWriter out = response.getWriter(); 
    16.         boolean isValid = tokenValidate(request);  
    17.         if(!isValid){ 
    18.            out.print("<script>alert('请不要重复提交,程序正在处理!');</script>"); 
    19.            return ;      
    20.         } 
    21.         out.println("正在向数据库注册用户信息!"); 
    22.          
    23.     } 
    24.  
    25.     private boolean tokenValidate(HttpServletRequest request) { 
    26.          String c_token = request.getParameter("c_token"); 
    27.          String s_token = (String) request.getSession().getAttribute("token"); 
    28.          //防止用户自定义html 
    29.          if(c_token==null
    30.              return false
    31.          if (s_token==null)  
    32.             return false
    33.          if (!s_token.equals(c_token))  
    34.             return false
    35.          request.getSession().removeAttribute("token"); 
    36.          return true
    37.     } 
    38.  
    39.     public void doPost(HttpServletRequest request, HttpServletResponse response) 
    40.             throws ServletException, IOException { 
    41.          doGet(request, response); 
    42.     } 
    package edu.form;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class RegistServlet extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		response.setCharacterEncoding("utf-8");
    		response.setContentType("text/html;charset=utf-8");
    		PrintWriter out = response.getWriter();
            boolean isValid = tokenValidate(request); 
            if(!isValid){
               out.print("<script>alert('请不要重复提交,程序正在处理!');</script>");
               return ; 	
            }
            out.println("正在向数据库注册用户信息!");
            
    	}
    
    	private boolean tokenValidate(HttpServletRequest request) {
             String c_token = request.getParameter("c_token");
             String s_token = (String) request.getSession().getAttribute("token");
             //防止用户自定义html
    		 if(c_token==null)
    			 return false;
    		 if (s_token==null) 
    			return false;
             if (!s_token.equals(c_token)) 
    			return false;
             request.getSession().removeAttribute("token");
    	     return true;
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
             doGet(request, response);
    	}
    }
    
    程序不能直接进入regist.jsp页面,只能通过http://localhost:8080/CookieAndSession/servlet/createform进入CreateFormServlet.java通过此Servlet跳转至注册页面

    此时http://localhost:8080/CookieAndSession/servlet/createform页面原代码如下:


    这样就可以解决以上三种可能出现的表单重复提交问题!

    展开全文
  • 表单重复提交

    2019-02-24 00:27:02
    在平时开发中,如果网速比较慢的情况下,或者远程有延迟,用户提交表单后,发现服务器半天都没有响应,那么用户... 表单重复提交的情况:  1.第一次单击提交之后,在没有提交成功情况下,又单击提交按钮。  ...

        在平时开发中,如果网速比较慢的情况下,或者远程有延迟,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,这样会出现表单的重复提交,造成向服务器发送两次请求,所以我们在开发中必须防止表单


    重复提交。

      表单重复提交的情况:

              1.第一次单击提交之后,在没有提交成功情况下,又单击提交按钮。

               2.提交完表单之后,刷新网页。

               3.用户提交表单后,点击浏览器的【后退】按钮回退到表单页面后进行再次提交。

      解决方案:

             网上很多解决办法,一下连接解决方案比较全面,还有图文演示:https://www.cnblogs.com/xdp-gacl/p/3859416.html

    自己解决办法:利用session,在表单中做一个标记,提交到servlet时候,检查标记是否在且和预定义标志一直,若一直,则受理请求,并销毁标记,若不一致,或者没有标记,则直接响应消息,“表单重复提交”。

       步骤:

                  》在原表单页面,随机生成一个token

                 》在原表单页面,将token值放入到session属性当中

                 》token属性值也放在隐藏域当中

                 》在目标页面中,:获取session和隐藏域token值,比较两个值是否一致,若一致,受理请求,且把session与中的session属性清除。

    表单页面 :

    <%@page import="org.apache.catalina.Session"%>
    <%@page import="java.util.Date"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
       <%
              String token=new Date().getTime()+"";
              HttpSession  sessio= request.getSession(true);
              sessio.setAttribute("token", token); 
       %>
    
       <h1>Step-1:选择要购买的书籍</h1>
       <form action="<%=request.getContextPath() %>/procesStep1" method="post">
            <input type="hidden"  name="token"  value="<%=token%>">
            <table cellpadding="10" cellspacing="0" border="1px">
                <tr>
                 <td>书名</td>
                 <td>购买</td>
                </tr>
                <tr>
                 <td>Java</td>
                 <td><input type="checkbox" name="book" value="java"></td>
                </tr>
                <tr>
                 <td>C++</td>
                 <td><input type="checkbox" name="book" value="c++"></td>
                </tr>
                <tr>
                 <td>Python</td>
                 <td><input type="checkbox" name="book" value="python"></td>
                </tr>
                <tr>
                 <td>web</td>
                 <td><input type="checkbox" name="book" value="web"></td>
                </tr>
                <tr>
                <td  colspan="2"> <input type="submit" value="submit"></td>
                </tr>
            </table>
            
       </form>
    
    </body>
    </html>

            目标服务器:   

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} 
    		//1550936037932
    		 String sessionToken = (String)request.getSession().getAttribute("token");
    		 String requestToken = request.getParameter("token");
    		 if(sessionToken!=null&&sessionToken.equals(requestToken)) {
    			 request.getSession().removeAttribute("token");
    		 }else {
    			 //request.getRequestDispatcher("/shoppingCart/relogin.jsp");
    			 response.sendRedirect(request.getContextPath()+"/shoppingCart/relogin.jsp");
    			 return ;
    		 }
    		 
    		//request.setCharacterEncoding("UTF-8");
    	    ServletContext servletContext = request.getServletContext();
    	    String servletContextName = servletContext.getServletContextName();
    	      ServletConfig servletConfig = getServletConfig();
    	     String[] parameterValues = request.getParameterValues("book");
    	     request.getSession().setAttribute("book", parameterValues);
    	     String contextPath = request.getContextPath();
    	     System.out.println(contextPath);
    	     //下面是绝对路径
    	     //   response.sendRedirect(contextPath+"/shoppingCart/step_2.jsp");
    	     //相对路径
    	     response.sendRedirect("shoppingCart/step_2.jsp");
    		
    	}

     

    展开全文
  • jsp客户端限制表单重复提交在客户端限制表单重复提交有两种方法: 第一种:在javascript脚本中设置一个标志变量,来区分表单是否已经提交。如果已经提交,则弹出对话框告诉用户“重复提交”。 第二种:在单击...
  • SP避免Form重复提交的三种方案   1) javascript ,设置一个变量,只允许提交一次。     var checksubmitflg = false;   function checksubmit() {   if (checksubmitflg == true) {   return false...
  • 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交 方法:1.生成一个...
  • JSP客户端限制表单重复提交

    千次阅读 2007-08-29 13:35:00
    在客户端限制表单重复提交有两种方法: 第一种:在javascript脚本中设置一个标志变量,来区分表单是否已经提交。如果已经提交,则弹出对话框告诉用户“重复提交”。 第二种:在单击提交按钮以后将提交按钮设置为...
  • 在客户端限制表单重复提交有两种方法: 第一种:在javascript脚本中设置一个标志变量,来区分表单是否已经提交。如果已经提交,则弹出对话框告诉用户“重复提交”。 第二种:在单击提交按钮以后将提交按钮设置为...
  • 防止表单重复提交

    2018-12-22 21:46:07
    开发的项目中可能会...这些情况都会导致表单重复提交,造成数据重复,增加服务器负载,严重甚至会造成服务器宕机。因此有效防止表单重复提交有一定的必要性。 解决方案: 一、 使用一个token(令牌)的机制  ...
  • 1.什么叫表单重复提交:  所谓表单重复提交,是指用户通过多次点击提交按钮或多次刷新表单提交页面等造成用户表单重复提交的现象 2.表单重复提交有哪些情况:  (1)用户在程序提交表单的时间段里多次提交表单  (2)...
  • 表单重复提交问题

    2017-08-16 09:07:32
    表单重复提交------同一表单的内容多次重复提交到服务器 比如插入数据时,同一表单多次提交,就会在数据库中插入多条重复的该条记录,造成严重的问题 表单重复提交分为三种情况: - 第一种情况: 提交完表单以后,...
  • 表单重复提交是在多用户Web应用中最常见、带来很多麻烦的一个问题。有很多的应用场景都会遇到重复提交问题,比如: 点击提交按钮两次。 点击刷新按钮。 使用浏览器后退按钮重复之前的操作,导致重复提交表单。 使用...
  • 表单重复提交

    2016-08-26 21:47:16
    一般做添加修改的功能时,要防表单重复提交,如果不限制就会影响后台的数据,会产生很多没用的垃圾数据,对性能也不好 第一步: 在struts.xml文件中添加或者修改方法配置token拦截器 第二步: 表单...
  • 表单重复提交解决方案(防止Http重复提交 场景模拟 创建一个from.jsp页面 &amp;lt;%@ page language=&quot;java&quot; contentType=&quot;text/html; charset=UTF-8&quot; pageEncoding=&...
  • 客户端:用JavaScript 定义一个局部变量,用来判断表单...1、用户可以把JavaScript语句删除,通过自己修改的表单页面重复提交; 2、刷新可以重复提交; 3、点后退又可以提交。 表单页面:form.html: My JSP 'inde
  • 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。 一、表单重复...
  • 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。 一、表单重复...
  • 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。 一、表单重复...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 25,595
精华内容 10,238
关键字:

jsp表单重复提交