方法一:前端提交后禁用按钮,弊端(如果电脑卡住,仍然可以连击)
方法二:后台处理
客户请求列表>>>>>获取key(此处用uuid)返回给前端,隐藏在list列表>>>>>>新增数据携带key,如果key不存在map中说明第一次请求,存入map。第二次请求会发现已经存在key,返回重复
每次刷新列表页都有新的key生成
具体代码实现:
1.建工具类
package com.saihao.common.util; import org.apache.commons.collections4.map.LRUMap; import java.util.UUID; /** * 幂等性判断 */ public class IdempotentUtils { /*根据 LRU(Least Recently Used,最近最少使用)算法淘汰数据的 Map 集合,最大容量 100 个*/ private static LRUMap<String, Integer> reqCache = new LRUMap<>(100); /** * 幂等性判断 * @return */ public static boolean judge(String id, Object lockClass) { synchronized (lockClass) { // 重复请求判断 if (reqCache.containsKey(id)) { return false; } // 非重复请求,存储请求 ID reqCache.put(id, 1); } return true; } /** * 防止数据重复提交的唯一令牌 * @return */ public static String getAloneToke() { return UUID.randomUUID().toString(); } /** * 数据返回失败后移除令牌,因为页面不刷新 * @return */ public static void removeAloneToke(String id) { reqCache.remove(id); } }
2.在请求列表中获取key,返回到前端界面
String aloneToke = IdempotentUtils.getAloneToke();
3.在前端加载list列表时为隐藏key赋值
$("#aloneToken").val(XXX);
4.提交时携带令牌,后台校验
if (!IdempotentUtils.judge(XXXX, this.getClass())) { return JsonResponse.fail("重复提交"); }
注意:如果提交失败不刷新列表,需要移除令牌