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

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

  ① 、当表单提交数据到一个 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. winform拖动无边框窗体

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

  2. Java进阶代码

    本文重在温习……不过初学以及进阶高手不可错过 1.  public static void arraycopy(全小写)(object src,int srcPos,object dest,int d ...

  3. 使用Qt编写模块化插件式应用程序

    动态链接库技术使软件工程师们兽血沸腾,它使得应用系统(程序)可以以二进制模块的形式灵活地组建起来.比起源码级别的模块化,二进制级别的模块划分使得各模块更加独立,各模块可以分别编译和链接,模块的升级不会 ...

  4. SQL中游标的使用

    一般情况下,我们用SELECT这些查询语句时,都是针对的一行记录而言,如果要在查询分析器中对多行记录(即记录集)进行读取操作时,则需要使用到游标或WHILE等循环 游标的类型:  1.静态游标(不检测 ...

  5. Intellij IDEA 14隐藏被排除的文件夹

    被排除的文件和文件夹以红色显示了. 看着这东西,人一下子就不好了. 还好设置可以改回来. Project tab右上角齿轮,关闭“Show Excluded Files”即可.

  6. 什么是券商PB业务

    PB业务(Prime Broker,主经纪商业务).所谓PB业务就是指向对冲基金等高端机构客户提供集中托管清算.后台运营.研究支持.杠杆融资.证券拆借.资金募集等一站式综合金融服务的统称.而该业务的基 ...

  7. 技能CDDemo(点击鼠标左键实现技能界面旋转)

    using UnityEngine; using System.Collections; using UnityEngine.UI; public class HealthController : M ...

  8. 图像的影像地图超链接,<map>标签浅谈

    在HTML中还可以把图片划分成多个热点区域,每一个热点域链接到不同网页的资源.这种效果的实质是把一幅图片划分为不同的热点区域,再让不同的区域进行超链接.这就是影像地图.要完成地图区域超链接要用到三种标 ...

  9. mysql去掉字段字符中间空格

    mysql有什么办法批量去掉某个字段字符中的空格?不仅是字符串前后的空格,还包含字符串中间的空格,答案是 replace,使用mysql自带的 replace 函数,另外还有个 trim 函数.   ...

  10. ListView列表拖拽排序

    ListView列表拖拽排序能够參考Android源代码下的Music播放列表,他是能够拖拽的,源代码在[packages/apps/Music下的TouchInterceptor.java下]. 首 ...