表单重复提交

来源:互联网 发布:负面情绪 知乎 编辑:程序博客网 时间: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中的数据为空,再判断用户提交的数据与服务器获取的数据是否相等,如果相等,则注册成功,如果不相等,则回显“验证码输入错误”。


原创粉丝点击