为什么需要防止表单重复提交呢?
重复提交不仅仅是验证的问题,有时候可能会出现重复执行业务逻辑。
比如你买东西付款,如果不禁制重复提交,用户心急点两次,或者误操作点两次,
结果扣两次钱,那这个网站还不得立刻死翘翘。
重复提交更多的时候是为了安全来。
-----:
1)包含有Form表单得页面必须通过一个服务器程序动态生成,服务器程序为每次产生得页面中的form表单都分配一个唯一得随机标识号,并在form表单得一个隐藏域 保存
(2)当用户提交form得时候,负责接受这一请求得服务器程序比较form表单隐藏字段中的标识号与存贮在session中的是否相同,当下列情情况时候,服务器程序将忽略提交请求:
a.当前用户session不存在表单标识
b.用户提交得表单数据并没有标识号字段
c.存贮在当前用户的session中得标识号与表单数据中的不同
重复提交不仅仅是验证的问题,有时候可能会出现重复执行业务逻辑。
比如你买东西付款,如果不禁制重复提交,用户心急点两次,或者误操作点两次,
结果扣两次钱,那这个网站还不得立刻死翘翘。
重复提交更多的时候是为了安全来。
-----:
1)包含有Form表单得页面必须通过一个服务器程序动态生成,服务器程序为每次产生得页面中的form表单都分配一个唯一得随机标识号,并在form表单得一个隐藏域 保存
(2)当用户提交form得时候,负责接受这一请求得服务器程序比较form表单隐藏字段中的标识号与存贮在session中的是否相同,当下列情情况时候,服务器程序将忽略提交请求:
a.当前用户session不存在表单标识
b.用户提交得表单数据并没有标识号字段
c.存贮在当前用户的session中得标识号与表单数据中的不同
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; public class TokenProcessor { private long privious;//上次生成表单标识号得时间值 private static TokenProcessor instance=new TokenProcessor(); public static String FORM_TOKEN_KEY="FORM_TOKEN_KEY"; private TokenProcessor(){ } public static TokenProcessor getInstance(){ return instance; } /* * 验证请求中得标识号是否有效,如果请求中的表单标识与当前用户session中的相同,返回结果true= */ public synchronized boolean isTokenValid(HttpServletRequest request){ //未避免session对象不存在时候创建Session对象 HttpSession session=request.getSession(false); if(session==null){return false;} String saved=(String)session.getAttribute(FORM_TOKEN_KEY); if(saved==null){ return false; } String token=(String)request.getParameter(FORM_TOKEN_KEY); if(token==null){ return false; } return saved.equals(token);//直接返回是否和浏览器页面是同一个token } /* * 清除存储在当前用户session中的表单标识号 */ public synchronized void reset(HttpServletRequest request){ HttpSession session=request.getSession(false); if(session==null){ return; } session.removeAttribute(FORM_TOKEN_KEY); } /* * 产生表单标识号并将之保存在当前用户得session中 */ public synchronized void saveToken(HttpServletRequest request){ HttpSession session=request.getSession(); try { byte id[]=session.getId().getBytes(); long current=System.currentTimeMillis(); if(current==privious){ current++; } privious=current; byte now[]=String.valueOf(current).getBytes(); MessageDigest md=MessageDigest.getInstance("MD5"); md.update(id); md.update(now); String token=toHex(md.digest()); session.setAttribute(FORM_TOKEN_KEY, token); } catch (NoSuchAlgorithmException e) { } } /* * 将一个字节数转换成十六进制得字符串 * */ public String toHex(byte buffer[]){ StringBuffer sb=new StringBuffer(buffer.length*2); for (int i = 0; i < buffer.length; i++) { sb.append(Character.forDigit((buffer[i]&0x60)>>4, 16)); sb.append(Character.forDigit(buffer[i]&0x0f, 16)); } return sb.toString(); } }
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 FormDoubleServlet extends HttpServlet { //提交的时候访问的servlet protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=gb2312"); PrintWriter out=response.getWriter(); TokenProcessor tokemProcessor=TokenProcessor.getInstance(); if(!tokemProcessor.isTokenValid(request)){ out.println("重复提交"); } String p1=request.getParameter("p"); if(p1==null||p1.trim().equals("")){ out.println("请输入内容"); }else{ out.println("提交内容被处理"); tokemProcessor.reset(request);//清除session中的标识 } } }
<%@ page contentType="text/html; charset=GBK"%> <% TokenProcessor tokemProcessor=TokenProcessor.getInstance(); tokemProcessor.saveToken(request); String token=(String)request.getSession().getAttribute(tokemProcessor.FORM_TOKEN_KEY); %> <html> <head> <title>用户登陆</title> </head> <body> <form action="/testServlet" method="post"> <input name="<%=tokemProcessor.FORM_TOKEN_KEY %>" value="<%=token %>"> <input name="q"/> <input type="submit" value="submit"/> </form> </body> </html>
发表评论
-
12306模型设计探讨
2016-04-28 14:10 667春节期间,无意中看到 ... -
Dubbo与Zookeeper、SpringMVC整合
2016-03-18 16:31 836互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构 ... -
TCP/IP,http,socket,长连接,短连接
2016-03-18 16:22 774TCP/IP TCP/IP是个协议组,可分为三个层次:网络层 ... -
移动互联网App客户端服务端通信安全问题。
2016-01-20 12:13 1589作为一个移动互联网App,天生是需要和服务器通信的。那么,服 ... -
前后端分离开发部署模式
2015-12-12 11:10 9764这周着手开始重新构 ... -
Jenkins + Git + Maven + tomcat集成环境(转)
2015-11-07 11:01 12548折腾了好几天,终于吧Jenkins + Git ... -
Apache Commons(转)
2012-08-31 11:36 805Apache Commons包含了很多开源的工具,用于解决平时 ... -
Cron 常用表达式
2012-08-31 11:34 2903Cron 常用表达式 <SELECT NAME=&qu ... -
httpSession的正确理解
2012-07-20 12:43 822httpSession的正确理解 ... -
图片码
2012-05-08 11:34 1199直接切入主题,2年前写的一个图片码,记录一下。 1 生成图片 ... -
jnlp
2012-05-08 10:59 4460java提供的一种让你可以通过浏览器直接执行java应用程序的 ... -
Spring Quartz 调度与Jdk Timer
2012-05-08 10:14 1823,最近经历的几个项目大多里面都使用到Spring Quart ... -
Dozer 深层次复制
2012-05-07 15:04 7860最近在做项目上遇到了 ... -
使用FreeMarker生成java代码
2012-05-07 14:36 36491 编写ftl模版; 2 编写java生成类(主要用来设置好 ...
相关推荐
主要介绍了浅谈利用Session防止表单重复提交,简单介绍表单重复提交的情况,分析,以及解决方法代码示例,具有一定借鉴价值,需要的朋友可以了解下。
struts2防止表单重复提交,利用struts的拦截器tokenSession,轻轻松松解决表单重复提交的问题。 附件为源代码,后台延迟了3秒,可直接在web服务器下部署运行,输入用户名和密码后,多点几次提交按钮,然后看控制台...
服务器端避免表单的重复提交,利用同步令牌来解决重复提交的基本原理如下:(1)用户访问提交数据的页面,服务器端在这次会话中,创建一个session对象,并产生一个令牌值,将这个令牌值作为隐藏输入域的值,随表单一起发送到...
PHP防止刷新重复提交,通过不断刷新(Refresh or Reload)表单提交页面,可以重复提交表单内容,可以利用 PHP 的 Session 来避免这一点,Session 保存在服务器端,在 PHP 过程中改变 Session 变量的值后,即保存在...
38.如何利用Session防止用户重复投票 40.如何在Session对象失效后重新设置Session对象 41.如何创建、读写和删除Cookie 43.如何遍历Cookies集合 44.如何判断客户端的Cookie是否处于开启状态 45.如何使用Cookie记录...
实例031 不提交表单获取单选按钮的值 43 实例032 选中单选按钮后显示其他表单元素 44 实例033 根据数据表结构自动生成数据录入页面 45 实例034 投票系统中单选按钮与复选框的应用 47 2.3 下拉列表的应用 ...
实例172 不提交表单获取单选按钮的值 207 实例173 实现复选框中的全选、反选和不选 208 实例174 隐藏域提交用户的ID值 210 实例175 图像域替代提交按钮 211 实例176 跳转菜单实现页面跳转 213 实例177 上传图片预览 ...
实例172 不提交表单获取单选按钮的值 207 实例173 实现复选框中的全选、反选和不选 208 实例174 隐藏域提交用户的ID值 210 实例175 图像域替代提交按钮 211 实例176 跳转菜单实现页面跳转 213 实例177 上传图片预览 ...
第15章防止重复提交 252 15.1 标记管理 252 15.2 使用Token拦截器 253 15.3 使用Token Session拦截器 256 15.4 小结 257 第16章调试与性能分析 258 16.1 debug标签 258 16.2 Debugging拦截器 259 16.3 性能...
第15章 防止重复提交 252 15.1 标记管理 252 15.2 使用Token拦截器 253 15.3 使用Token Session拦截器 256 15.4 小结 257 第16章 调试与性能分析 258 16.1 debug标签 258 16.2 Debugging拦截器 259 16.3 性能分析 ...
SubmitOncePage:解决刷新页面造成的数据重复提交问题 SharpRewriter:javascript + xml技术利用#实现url重定向 采用XHTML和CSS设计可重用可换肤的WEB站点 asp.net的网址重定向方法的比较:面向搜索引擎友好 也谈 ...
8 <br>0018 有效利用Visual Studio 2005附带程序 8 <br>0019 有效使用MSDN帮助 9 <br>0020 如何设置MSDN帮助 9 <br>1.4 其他 10 <br>0021 如何添加项目引用 10 <br>0022 如何添加Web...