防止重复提交可以通过前端拦截校验和后端拦截校验的方式,在此对后端拦截进行重复提交判断进行尝试。
后端拦截的实现思路是在方法执行之前,先判断此业务是否已经执行过,如果执行过则不再执行,否则就正常执行。我们将请求的业务 ID 存储在内存中,并且通过添加互斥锁来保证多线程下的程序执行安全,将数据存储在内存中,最简单的方法就是使用 HashMap 存储,或者是使用 Guava Cache 也是同样的效果,但很显然 HashMap 可以更快的实现功能,所以我们先来实现一个 HashMap 的防重(防止重复)版本。
升级方法是加上双重检测锁DCL;再升级方法是采用LRUMap实现;
代码示例:
public class IdempotentUtil {
//根据LRU算法淘汰最近最少使用的数据的Map集合,最大容量100个
private static LRUMap<String,Integer> lruMap = new LRUMap<>(100);
/**
* 幂等性判断
*/
public static boolean check(String id, Object lockClass) {
synchronized (lockClass) {
//重复请求判断
if (lruMap.containsKey(id)) {
//重复请求
System.out.println("请勿重复提交..." + id);
return false;
}
//非重复请求,存储ID
lruMap.put(id,1);
}
return true;
}
}@RequestMapping("addUser6")
public String addUser(String id) {
//调用幂等性工具判断
if (!IdempotentUtil.check(id,this.getClass())) {
return "请求失败";
}
//业务代码
System.out.println("添加用户ID:" + id);
return "请求成功";
}需要使用Maven引用包
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.4</version> </dependency>
