`
shaohan126448
  • 浏览: 115845 次
  • 来自: 北京
社区版块
存档分类
最新评论

Struts1实现防表单重复提交

 
阅读更多

什么情况下会导致重复提交?

1.网络延迟,当用户提交后由于网络的原因在等待提交,如果这个时候用户再次点击提交按钮的话就会导致重复提交。

2.如果提交以后,这时用户如果点击刷新按钮的话,就会重复的提交。

3.用户提交以后,如果用户点击返回按钮,再点击提交也会实现重复提交。

解决方法有两种:

1.在客户端使用javaScript防表单重复提交

2.在服务器端写程序防重复提交

 

示例:客户端使用javaScript防表单重复提交

Html代码 复制代码
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  2. <html>  
  3.   <head>  
  4.     <title>form.html</title>  
  5.     <meta http-equiv="content-type" content="text/html; charset=UTF-8">  
  6.     <script type="text/javascript">  
  7.         var iscommiteed = false;    
  8.         function formsubmit(){   
  9.             if(!iscommiteed){   
  10.                 iscommiteed = true;   
  11.                 return true;   
  12.             }else{   
  13.                 alert("请不要重复提交!!");   
  14.                 return false;   
  15.             }      
  16.                
  17.         }   
  18.     </script>  
  19.   </head>  
  20.   <body>  
  21.     <form action="/day06/servlet/RegisterServlet" method="post" onsubmit="return formsubmit()">  
  22.         用户名:<input type="text" name="username">  
  23.         <input type="submit" value="注册">  
  24.     </form>  
  25.   </body>  
  26. </html>  


这种提交只能防住第一种(网络延迟),后两种是防不住,三种为了都能防住只能在服务器端写程序防重复提交。

服务器端写程序防重复提交实现原理:

当用户提交的时候,系统首先需要生成一个随机号,在服务器端进行保存并在jsp表单中绑定这个生成的随机号,当jsp表单提交时服务器端接收用户提交的这个随机号然后与服务器端保存的随机号进行对比,如果随即号相同的话,执行提交操作,并把服务器端保存的随机号销毁。如果不同的话提示用户重复提交。

示例:生成随机数

Html代码 复制代码
  1. package cn.itcast.form;   
  2.   
  3. import java.io.IOException;   
  4. import java.security.MessageDigest;   
  5. import java.security.NoSuchAlgorithmException;   
  6. import java.util.Random;   
  7. import java.util.UUID;   
  8.   
  9. import javax.servlet.ServletException;   
  10. import javax.servlet.http.HttpServlet;   
  11. import javax.servlet.http.HttpServletRequest;   
  12. import javax.servlet.http.HttpServletResponse;   
  13.   
  14. import sun.misc.BASE64Encoder;   
  15.   
  16. public class FormServlet extends HttpServlet {   
  17.   
  18.     public void doGet(HttpServletRequest request, HttpServletResponse response)   
  19.             throws ServletException, IOException {   
  20.            
  21.         String token = TokenProcessor.getInstance().getToken();   
  22.         request.getSession().setAttribute("token", token);   
  23.         request.getRequestDispatcher("/form.jsp").forward(request, response);   
  24.     }   
  25.   
  26.     public void doPost(HttpServletRequest request, HttpServletResponse response)   
  27.             throws ServletException, IOException {   
  28.   
  29.         doGet(request, response);   
  30.     }   
  31. }   
  32.   
  33. //令牌(随机数生成器)   
  34. class TokenProcessor{   
  35.        
  36.     /**   
  37.      * 1.把构造方法私有   
  38.      * 2.自己创建一个对象   
  39.      * 3.定义一个方法,让别人获取这个对象   
  40.      *    
  41.      */   
  42.        
  43.     private TokenProcessor(){}   
  44.     private static final TokenProcessor instance = new TokenProcessor();   
  45.     public static TokenProcessor getInstance(){   
  46.         return instance;   
  47.     }   
  48.        
  49.     public String getToken(){   
  50.            
  51.         String token  =  System.currentTimeMillis() + new Random().nextInt(1000000) + "";   
  52.            
  53.         //md5  数据指纹 消息摘要    
  54.         try {   
  55.             MessageDigest digest = MessageDigest.getInstance("md5");   
  56.             byte md5[] = digest.digest(token.getBytes());  //任意的16个字节  3434   
  57.                
  58.             //Base64编码   
  59.             //BASE64Encoder encoder = new BASE64Encoder();   
  60.             //return encoder.encode(md5);   
  61.                
  62.             return toHex(md5);   
  63.         } catch (NoSuchAlgorithmException e) {   
  64.             throw new RuntimeException(e);   
  65.         }   
  66.         //return UUID.randomUUID().toString();   
  67.     }   
  68.        
  69.     public String toHex(byte b[]){   
  70.         StringBuffer sb = new StringBuffer();   
  71.            
  72.         for(int i=0;i<b.length;i++){   //1100 0011   
  73.             sb.append(Character.forDigit(b[i]&15,16));  //10  A   9  9    12  C   
  74.             sb.append(Character.forDigit(b[i]>>4&15,16));   
  75.         }   
  76.            
  77.         return sb.toString();   
  78.     }   
  79. }  

 

 

服务器端验证:

Html代码 复制代码
  1. package cn.itcast.form;   
  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 RegisterServlet extends HttpServlet {   
  10.   
  11.     public void doGet(HttpServletRequest request, HttpServletResponse response)   
  12.             throws ServletException, IOException {   
  13.         //防表单重复提交   
  14.         boolean b = isValid(request);   
  15.         if(!b){   
  16.             System.out.println("表单是重复提交!!");   
  17.             return;   
  18.         }   
  19.         request.getSession().removeAttribute("token");   
  20.            
  21.         String username = request.getParameter("username");   
  22.            
  23.         try {   
  24.             Thread.sleep(1000*5);   
  25.         } catch (InterruptedException e) {   
  26.             // TODO Auto-generated catch block   
  27.             e.printStackTrace();   
  28.         }   
  29.         System.out.println("向数据库注册用户");   
  30.         System.out.println("注册成功!!");   
  31.     }   
  32.     //校验客户机带过来随即号否有效   
  33.     private boolean isValid(HttpServletRequest request) {   
  34.            
  35.         String c_token = request.getParameter("token");   
  36.         if(c_token==null || c_token.equals("")){   
  37.             return false;   
  38.         }   
  39.            
  40.         String s_token = (String) request.getSession().getAttribute("token");   
  41.         if(s_token==null){   
  42.             return false;   
  43.         }   
  44.            
  45.         if(!c_token.equals(s_token)){   
  46.             return false;   
  47.         }   
  48.            
  49.         return true;   
  50.     }   
  51.   
  52.     public void doPost(HttpServletRequest request, HttpServletResponse response)   
  53.             throws ServletException, IOException {   
  54.   
  55.         doGet(request, response);   
  56.     }   
  57. }  

 

 

用Struts1防重复提交:

 

以上示例就是模拟struts1来提交的,原理是一样的,如果用struts1来实现访重复提交会更加简单,struts1内部封装了很多操作。

注意:jsp页面中只需用struts标签的form表单就可以自动获取表单号。

示例:生成随机数

Html代码 复制代码
  1. package cn.itcast.web.action;   
  2.   
  3. import javax.servlet.http.HttpServletRequest;   
  4. import javax.servlet.http.HttpServletResponse;   
  5.   
  6. import org.apache.struts.action.Action;   
  7. import org.apache.struts.action.ActionForm;   
  8. import org.apache.struts.action.ActionForward;   
  9. import org.apache.struts.action.ActionMapping;   
  10.   
  11. public class RegisterUIAction extends Action {   
  12.   
  13.     @Override   
  14.     public ActionForward execute(ActionMapping mapping, ActionForm form,   
  15.             HttpServletRequest request, HttpServletResponse response)   
  16.             throws Exception {   
  17.         //产生一个表单号,并存储到session域中   
  18.         saveToken(request);   
  19.         return mapping.findForward("registerUI");   
  20.     }   
  21. }  


服务器端验证:

Html代码 复制代码
  1. package cn.itcast.web.action;   
  2.   
  3. import javax.servlet.http.HttpServletRequest;   
  4. import javax.servlet.http.HttpServletResponse;   
  5.   
  6. import org.apache.struts.action.Action;   
  7. import org.apache.struts.action.ActionForm;   
  8. import org.apache.struts.action.ActionForward;   
  9. import org.apache.struts.action.ActionMapping;   
  10.   
  11. import cn.itcast.web.formbean.RegisterFormBean;   
  12.   
  13. //防表单重复提交   
  14. public class RegisterAction extends Action {   
  15.   
  16.     @Override   
  17.     public ActionForward execute(ActionMapping mapping, ActionForm form,   
  18.             HttpServletRequest request, HttpServletResponse response)   
  19.             throws Exception {   
  20.            
  21.         //校验表单提交的是否有效,如果有效的话就要把表单号清掉(true的含义)   
  22.         boolean b = this.isTokenValid(request,true);   
  23.         if(!b){   
  24.             System.out.println("重复提交");   
  25.             return null;   
  26.         }   
  27.         RegisterFormBean formbean = (RegisterFormBean) request.getAttribute("registerFormBean");   
  28.         try{   
  29.             System.out.println("向数据库注册" + formbean.getUsername());   
  30.             request.setAttribute("message", "注册成功!!");   
  31.             return mapping.findForward("message");   
  32.         }catch (Exception e) {   
  33.             e.printStackTrace();   
  34.             request.setAttribute("message", "注册失败!!");   
  35.             return mapping.findForward("register");   
  36.         }   
  37.     }   
  38. }  
分享到:
评论

相关推荐

    Struts2解决表单重复提交

    Struts2作为一个流行的Java Web框架,为解决表单重复提交提供了多种方法。 首先,关于表单重复提交的原因,有以下几点: 1. 服务器或网络延迟导致用户多次点击提交按钮。 2. 用户在表单提交后刷新浏览器页面。 ...

    struts2 防止表单重复提交的例子

    1. **表单重复提交问题**:当用户在提交表单时,由于网络延迟或用户误操作,可能会导致同一个表单被多次提交。例如,在购物网站上,用户可能因点击按钮太快而无意中购买了多份商品。 2. **Struts2框架**:Struts2是...

    struts2利用token防止表单重复提交(源代码)

    struts2防止表单重复提交,利用struts的拦截器tokenSession,轻轻松松解决表单重复提交的问题。 附件为源代码,后台延迟了3秒,可直接在web服务器下部署运行,输入用户名和密码后,多点几次提交按钮,然后看控制台...

    struts token机制解决表单重复提交

    Struts Token机制是一种防止表单重复提交的有效策略,尤其在处理关键操作时,如金融交易或数据修改,防止用户意外或恶意多次点击提交按钮导致的数据重复性问题。下面将详细介绍Struts Token的工作原理、实现方式及其...

    Servlet、Struts、SpringMVC对于表单重复提交的解决方案

    总结来说,Servlet、Struts和SpringMVC都提供了各自的解决方案来防止表单重复提交,主要方法包括使用Session、令牌机制、重定向和拦截器等。开发者可以根据项目需求选择合适的方式来实现,确保应用的稳定性和数据...

    Struts2防止表单重复提交示例

    在Struts2中防止表单重复提交的过程主要包括以下几个步骤: 1. **生成Token**:当用户发起表单请求时,服务器会生成一个唯一的Token并将其存储在服务器的会话(Session)中,同时将这个Token作为隐藏字段放入到HTML...

    Struts之Token解决表单那重复提交

    综上所述,Struts框架通过Token机制有效地解决了表单重复提交的问题,提供了更健壮的Web应用安全性。正确理解和应用这一机制对于Java Web开发者来说至关重要。在实际项目中,结合其他防御策略,如CSRF防护,可以...

    struts2防止表单重复提交--重定向

    下面将详细解释Struts2如何通过重定向来防止表单重复提交。 首先,理解表单重复提交的场景:用户在提交表单后,由于网络延迟或其他原因,可能会无意中多次点击提交按钮。如果服务器没有处理这些重复请求,那么相同...

    struts+token机制解决表单重复提交

    在提供的压缩包文件"struts+token机制解决表单重复提交"中,可能包含了具体的Struts配置文件、Action类、Interceptor实现以及示例代码,可以帮助读者更深入地理解并实践这个机制。通过对这些代码的学习和研究,...

    Struts2防止重复提交解决方案

    在Struts2中,防止重复提交是一个重要的问题,因为它可能导致数据不一致性和服务器资源的浪费。本文将详细介绍如何在Struts2中解决这个问题,以及相关的技术概念。 首先,我们要理解Struts2中的拦截器(Interceptor...

    防止表单重复提交

    对于Struts2框架,我们可以结合以上策略来实现防止表单重复提交。Struts2提供了拦截器(Interceptor)机制,可以自定义拦截器来处理表单提交。例如,可以创建一个Token拦截器,生成和验证令牌。以下是一个简单的步骤...

    Struts2 表单 重复提交

    "防止表单重复提交 token"是Struts2提供的一种解决方案,通过在请求中加入一个唯一的token来确保请求的唯一性和一致性。 首先,我们来看如何实现这个机制。在Struts2中,我们可以使用拦截器(Interceptor)来实现...

    struts2令牌解决页面重复提交问题

    在Web开发中,一个常见的问题就是防止用户意外或恶意地重复提交表单,这可能导致数据的不一致性和服务器负载的增加。Struts2提供了一种称为“令牌”或“Token Session”的机制来解决这个问题。 令牌机制的工作原理...

    Struts2文件上传下载和表单重复提交问题

    在实际应用中,文件上传和下载以及防止表单重复提交是两个常见的需求,同时也是开发者必须掌握的重要技能。 1. **文件上传** 文件上传功能在Struts2中通过`Struts2`提供的插件来实现,主要依赖于`Apache Commons ...

    Struts表单重复提交问题

    为了防止这种表单重复提交,Struts提供了一种令牌(Token)机制。令牌机制的工作原理如下: 1. **设置令牌**:在用户访问表单之前,Action类中的`execute`方法会调用`saveToken`方法,将一个唯一的令牌保存在请求...

    struts数据回显、模型驱动、防止表单重复提交

    综上所述,理解并掌握Struts框架中的数据回显、模型驱动以及防止表单重复提交的原理和实现方法,对于提升Java Web应用的开发效率和质量具有重要意义。在实际开发中,应灵活运用这些技术,以满足项目需求,打造稳定...

    【原创】Struts2防止表单重复提交.doc

    ### Struts2防止表单重复提交的技术解析 #### 一、引言 在Web应用程序开发过程中,表单重复提交是一个常见的问题,特别是在网络环境不稳定或用户误操作的情况下。这种重复提交不仅可能导致数据冗余,还可能引起事务...

Global site tag (gtag.js) - Google Analytics