下面我们首先来说一下表单的重复提交问题,我们知道在真实的网络环境中可能受网速带宽的原因会造成页面中表单在提交的过程中出现网络的延迟等问题,从而造成多次提交的问题!下面我们就具体来分析一下造成表单提交的一些常见问题。

下面我们就来列举一下重复提交的情况:

  ① 、当表单提交数据到一个 Servlet 中,然后 Servlet再通过请求转发到成功页面,但是此时的地址栏中的地址是到 Servlet映射中的地址,并没有跳转到成功页面相关的JSP页面中,此时刷新页面会造成再一次提交表单。

  ② 、当在表单页面中点击提交按钮时,表单页面没有立即跳转到Servlet来进行处理(网络延迟),而此时用户就点击多次提交按钮,也会造成重复提交表单!

  ③ 、当用户进行表单数据提交成功后,又通过浏览器上的返回按钮返回到提交表单页面,(在不进行刷新到条件下)再次进行点击提交也会造成重复提交表单的情况!这是因为在不进行刷新的情况下页面的表单数据是浏览器第一次提交的缓存,故而进行提交的还是第一次提交的数据。而进行刷新后则是一个新的request请求!

对此我们如何进行防止表单的重复提交呢?下面我们来进行说一下:

    ①  . 我们提供一个隐藏域: <input type="hidden" name="token" value="vincent"/>.来进行作为标记。这时我们发现当我们将数据提交到Servlet中时,没有方法清除固定的请求参数(即:标记).所以该方案是行不通的!

    ②  . 把标记放在 request 中.这时虽然我们可以通过作用域的removeAttribute(str);方法将标记进行删除 但是当我们请求表单页面时虽然将标记保存到request中, 而我们点击提交按钮时,将会向Servlet重新提交一个新的request,而此时第一个request已经失去了它的作用域(我们知道request只能在一次请求之间有效!)被销毁掉,故而无法在目标Servlet中获取到第一request设置的属性(标记),所以该方案也行不通!

    ③. 把标记放在 session 中. 可以!同时我们也可以使用隐藏域来帮助我们将标记变成一个随机值。

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

   String tokenValue = new Data().getTime() + “”;

    (使用时间来作为随机值,还不够随机,不过暂时对于我们学习而言还可以,切记在工作中使用时间来作为随机值,因为在大量的用户访问我们的产品时,时间就不能作为随机数了)

  > 在原表单页面, 把 token 值放入 session 属性中

   session.setAttribute(“token”,tokenValue);

  > 在原表单页面, 把 token 值放入到 隐藏域 中.

  <input type=”hidden” name=”token”value=<%=tokenValue%> />

   > 在目标的 Servlet 中: 获取 session 和 隐藏域 中的 token 值

  Object token =  request.getSession.getAttribute(“token”);

  String tokenValue = request.getParameter(“token”);

   > 比较两个值是否一致: 若一致, 受理请求, 且把 session 域中的 token 属性清除

  > 若不一致, 则直接响应提示页面: "重复提交"

    if( token != null && token.equals(tokenValue)){

    session.removeAttribute(“token”);

    }else{

    response.sendRedirect("repeated.jsp");//响应提示页面: "重复提交"

    }

    response.sendRedirect("success.jsp");

以上就可以解决表单重复提交的问题了!此外当我们在框架中如Struts1、Struts2、SpringMVC中也可以看到它们也提供了相应的解决方法!


下面我们来说一下,关于验证码的问题:

对于为什么要使用验证码的原因相信大家都知道在此就不在赘述了!其实对于验证码来说,和防止表单重复提交一样的原理一样。

> 在原表单页面, 生成一个验证码的图片, 生成图片的同时, 需要把该图片中的字符串放入到 session 中.

> 在原表单页面, 定义一个文本域, 用于输入验证码.

> 在目标的 Servlet 中: 获取 session 和 表单域 中的 验证码的 值

> 比较两个值是否一致: 若一致, 受理请求, 且把 session 域中的 验证码 属性清除

> 若不一致, 则直接通过重定向的方式返回原表单页面, 并提示用户 "验证码错误"

JavaWeb 之 重复提交表单和验证码相关的问题!的更多相关文章

  1. JavaWeb -- Struts1 使用示例: 表单校验 防表单重复提交 表单数据封装到实体

    1. struts 工作流程图 超链接 2. 入门案例 struts入门案例: 1.写一个注册页面,把请求交给 struts处理 <form action="${pageContext ...

  2. Struts2 token禁止重复提交表单

    如果服务器响应慢的情况下,用户会重复提交多个表单,这时候有两种设计思想: 1.在客户端使用JS技术,禁止客户重复提交表单.但是这样会使一些不使用浏览器方式登陆的人比如使用底层通信来攻击你的服务器 2. ...

  3. Ajax实现提交表单时验证码自动验证(原创自Zjmainstay)

    本文通过源码展示如何实现表单提交前,验证码先检测正确性,不正确则不提交表单,更新验证码. 1.前端代码 index.html <!DOCTYPE html> <html> &l ...

  4. PHP防止用户重复提交表单

    我们提交表单的时候,不能忽视的一个限制是防止用户重复提交表单,因为有可能用户连续点击了提交按钮或者是攻击者恶意提交数据,那么我们在提交数据后的处理如修改或添加数据到数据库时就会惹上麻烦. 那么如何规避 ...

  5. struts2中token防止重复提交表单

    struts2中token防止重复提交表单 >>>>>>>>>>>>>>>>>>>&g ...

  6. 关于Asp.Net中避免用户连续多次点击按钮,重复提交表单的处理

    Web页面中经常碰到这类问题,就是客户端多次点击一个按钮或者链接,导致程序出现不可预知的麻烦. 客户就是上帝,他们也不是有意要给你的系统造成破坏,这么做的原因很大一部分是因为网络慢,点击一个操作之后, ...

  7. php防止重复提交表单

    解决方案一:引入cookie机制来解决 提交页面代码如下a.php代码如下: <form id="form1" name="form1" method=& ...

  8. spring mvc 防止重复提交表单的两种方法,推荐第二种

    第一种方法:判断session中保存的token 比较麻烦,每次在提交表单时都必须传入上次的token.而且当一个页面使用ajax时,多个表单提交就会有问题. 注解Token代码: package c ...

  9. Ajax提交表单时验证码自动验证 php后端验证码检测

    本文通过源码展示如何实现表单提交前,验证码先检测正确性,不正确则不提交表单,更新验证码. 1.前端代码 index.html <!DOCTYPE html> <html> &l ...

随机推荐

  1. 原生网络请求:同步请求、异步请求、GET请求、POST请求

    1.同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作, 2.异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然 ...

  2. Install RHadoop with Hadoop 2.2 – Red Hat Linux

    Prerequisite Hadoop 2.2 has been installed (and the below installation steps should be applied on ea ...

  3. winform拖动无边框窗体

    这个无边框拖动船体,代码很少,却总是记不住,于是就在网上搜了这段代码,记录一下,省的再忘 using System; using System.Collections.Generic; using S ...

  4. 如何将github上的微信客户端类库能够通过composer工具下载

    我将自己开发的微信客户端类库放到了github上面去了. 然后我在我的项目里面添加了一个composer.json文件 内容如下 { "require": { "weix ...

  5. 关于如何将C语言源文件转化为汇编文件

    --转载自:http://blog.21ic.com/user1/6088/archives/2010/68469.html 方法:(假设当前工程中只有一个C代码文件) 第1步:新建一个工程,添加C文 ...

  6. 【动态规划】Codeforces 706C Hard problem

    题目链接: http://codeforces.com/contest/706/problem/C 题目大意: n(2 ≤ n ≤ 100 000)个字符串(长度不超过100000),翻转费用为Ci( ...

  7. yui--datatable 更新table数据

    使用render可以重新渲染datatable,之前添加的样式等信息也想相应会初始化,另外行定位等也会失效 使用updateRows方法不会删除样式等信息 更新datasource中_oData数据 ...

  8. 线程间同步之 semaphore(信号量)

    原文地址:http://www.cnblogs.com/yuqilin/archive/2011/10/16/2214429.html semaphore 可用于进程间同步也可用于同一个进程间的线程同 ...

  9. C - A Simple Problem with Integers - poj 3468(区间更新)

    题意:有一个比较长的区间可能是100000.长度, 每个点都有一个值(值还比较大),现在有一些操作,C abc, 把区间a-b内全部加上c, Qab,求区间ab的值. 分析:很明显我们不可能对区间的每 ...

  10. HDU1007 Quoit Design 【分治】

    Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...