web-避免表单重复提交

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xingxingmingyue/article/details/50960723
1 在点击提交表单的按钮,在表单验证通过之后吧按钮设置为不可点击,代码如下:

优点:简单,易懂,直接用js解决。
缺点:这种方式是一种治标不治本的,只是在页面上提交表单起作用,但是通过http的方式请求,表单一样的重复提交。
2 使用Token令牌的方式解决:
 思路说明:在有表单提交的jsp页面中生成一个token(其实都是一个随机数),并且把这个token存入session中,然后在要提交的表单中添加一个隐藏的input来存放token的值,这样表单提交的时候就会携带token一起提交,然后在对表单的处理方法中对token进行校验,校验通过,就执行表单处理相关操作,并且将session中的token去除掉。

1) token处理类如下:
package com.adtech.libraryunion.filter;

import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class TokenGen {
    private static TokenGen instance = new TokenGen();
    private TokenGen() {}
    //获取TokenGen实例对象
    public static TokenGen getInstance() {
        return instance;
    }
    //token校验
    public synchronized boolean isTokenValid(HttpServletRequest request,String token) {
        // 没有session,判为非法
        HttpSession session = request.getSession(false);//false如果没有session对象,就返回一个null
        if (session == null)
            return false;

        // session中不含token, 判为非法
        String stoken = (String) session.getAttribute("token");
        if (stoken == null)
            return false;

        // request请求中的token与session中保存的token不等,判为非法
        return stoken.equals(token);
    }

    /*
     * 重新设置token,当页面被请求后,将session中的token属性去除
     */
    public synchronized void resetToken(HttpServletRequest request)
    {
        HttpSession session = request.getSession(false);
        if (session!=null)
        {
            session.removeAttribute("token");
        }
    }
    /*
     * 为请求新建一个token标记,此标记由一个随机的double数toString形成,并把字符值存入session中
     */

    public synchronized void saveToken(HttpServletRequest request)
    {
        //true表示如果没有session对象就返回一个新的session对象
        HttpSession session = request.getSession(true);
        Random rand = new Random();
        Double d = rand.nextDouble();
        session.setAttribute("token", d.toString());   
    }
}
在有jsp表单提交页面中添加如下代码:

在要提交的表单中添加如下:

说明:对于文件上传的表单,因为表单的enctype=" multipart/form-data ",表示表单一流的方式传入后台的,表单携带的普通参数将会是以二进制的形式传入后台,所以在后台不能通过request.getParamter()的方式获取到参数,对于这种最好是在controller中的处理方法中去校验token,但是对于一般的表单,可以写一个过滤器来实现,在过滤器中对token进行校验。如果要实现所有表单的避免重复提交最好还是在处理表单的方法中对token做校验。

下面为在controller中处理表单方法中校验token代码:
 MultipartHttpServletRequest是spring中的一个类,可以通过把request强转为此对象获取enctype="multipart/form-data"表单中的参数和文件流


使用token的方式处理:
优点:是从根本上解决问题,既使有人通过http的方式也是可以避免重复提交的。
缺点:处理的方式要繁琐一些。

猜你喜欢

转载自blog.csdn.net/xingxingmingyue/article/details/50960723