表单重复提交
来源:互联网 发布:负面情绪 知乎 编辑:程序博客网 时间:2024/04/30 09:46
思想:通过验证码的形式防止表单重复提交。
通过JavaEE实现:
思路:
1,写一个表单,比如是用户注册表单,在表单中定义一个img标签,将src指定为一个servlet,这个servlet将动态生成一个验证码图片,也就是每次请求这个页面的时候都会生成一个新的验证码。
2,Servlet生成验证码,在这个servlet生成验证码之后,要将这个验证码的值存放在session中,用户放置重复提交,用到的token机制(令牌机制)。Servlet生成验证码的代码如下:
public class VerifyCodeServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//产生验证码。//首先准备一些数据。String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";//准备随机函数,从这些数据中随机取值,Random random = new Random();int width = 60;int height = 30;//创建图像。BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);//创建画板。Graphics g = image.getGraphics();//设置画笔颜色。g.setColor(Color.BLACK);//填充矩形。g.fillRect(0, 0, width, height);g.setColor(Color.WHITE);g.fillRect(1, 1, width-2, height-2);//设置字体。g.setFont(new Font("宋体",Font.BOLD,20));//创建一个StringBuilder来构建随机生成 的四位验证码StringBuilder sb = new StringBuilder();//用循环获取4为随机码。for(int i=0;i<4;i++) {//设置随机颜色。g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));//获得随机字符。int index = random.nextInt(data.length());String str = data.substring(index, index+1);//添加到缓冲的sb中。sb.append(str);//绘制到画板中。g.drawString(str,width/6*(i+1),20);}//将数据缓存到session,以便于在检查的servlet中进行验证码的比对。String bufferData = sb.toString();request.getSession().setAttribute("sessionVerifyCodeData", bufferData);//添加干扰点,线for(int i=0;i<5;i++) {g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));}//将服务器内存中的数据发送到浏览器。ImageIO.write(image,"jpg",response.getOutputStream());}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}
3,用户填好验证码表单,提交到servlet,servlet先获取到用户提交的验证码,再获取服务器的验证码。首先判断服务器获取的验证码是否为空,如果是null,则提示用户“重复提交”,让用户重新刷新页面,重新提交。如果服务器有数据,则先将服务器的session中的数据删除,保证用户重复提交的时候服务器的session中已经没有数据,删除之后再判断session中的数据是否与用户提交的数据一致,一致则注册成功,不一致则返回信息提示用户验证码错误。
//判断验证码----------------------------------------------------------------------//获取用户填写的验证码String verifyCode = request.getParameter("verifyCode");//获取session中的验证码,如果二者一致,则填写正确。String sessionVerifyCodeData = (String)request.getSession().getAttribute("sessionVerifyCodeData");//首先判断服务器是否有session中的验证码数据。if(sessionVerifyCodeData!=null) {//有数据。将session中缓存的数据移除,保证验证码的一次性,request.getSession().removeAttribute("sessionVerifyCodeData");if(!sessionVerifyCodeData.equalsIgnoreCase(verifyCode)) {//如果不匹配request.setAttribute("message", "验证码有误,请重新填写");request.getRequestDispatcher("/client/register.jsp").forward(request, response);return;} } else {//重复提交request.setAttribute("message", "不要重复提交");request.getRequestDispatcher("/client/register.jsp").forward(request, response);return;}
4,验证。
Struts2实现:
核心步骤:
(1) 在jsp页面写一个<s:token /> 标签。
(2) 在struts.xml中配置信息。配置拦截器,在当前的action中,加入defaultStack默认拦截器,在添加一个拦截器引用,引用token拦截器,使token拦截器追加到默认拦截器后面。在token中配置参数,参数名为includeMethods,用户说明这个token用于当前action类的那个方法,我们默认在注册方法register中。
(3) 设定错误处理信息,result接收的是invalid.token,再配置国际化文件,在当前Action所在目录中写一个properties文件,根据返回的英文信息,去default.properties中查询相应的键,在自定义的properties中将这个键用自己的信息覆盖即可。
实现原理:
基本与JavaEE的方式相同,首先,在jsp中定义一个<s:token />标签,当浏览器访问这个jsp时,<s:token />标签会自动生成一个随机数据,保存到服务器的session中,并在当前jsp中的一个隐藏域中记录这个随机生成的数据,当用户提交表单时,会将隐藏域中的数据带到服务器,服务器获取用户提交的信息,即这个随机码,再从服务器的session中获取数据。先判断服务器获取的数据是否是空,如果是空,则表明用户重复提交了数据,返回错误信息。如果不是空,则用户时第一次提交,先将服务器的session中的数据删除,以便于用户重复提交的时候session中的数据为空,再判断用户提交的数据与服务器获取的数据是否相等,如果相等,则注册成功,如果不相等,则回显“验证码输入错误”。
- 防止表单重复提交
- 解决表单重复提交
- 防止重复提交表单
- 避免表单重复提交
- 避免表单重复提交
- 表单的重复提交
- 避免表单重复提交
- 限制表单重复提交
- 表单重复提交
- 防止表单重复提交
- 防止表单重复提交
- 防止表单重复提交
- 防止表单重复提交
- 防止表单重复提交
- JSP表单重复提交
- jsp表单重复提交
- 防止表单重复提交
- 解决表单重复提交
- 多线程同步-mutex
- 动态代理
- Irrlicht学习之创建GUI界面
- 字符串的内容一旦声明则不可改变 Why?
- STL中优先队列的使用方法
- 表单重复提交
- jsp连接mysql数据库
- (阶段三 dijkstra1.4)HDU 1596 find the safest road(最短路的变形题:求乘积,求最大值)
- EL表达式语言
- Linux下C++动态库的生成和使用
- 数论基础练习赛-解题报告
- John
- 碎片攻击
- C++中引用和指针的区别