素材巴巴 > 程序开发 >

后端--防重复提交策略方法

程序开发 2023-09-21 08:01:04

后端–防重复提交策略方法

原因:

前台操作的抖动,快速操作,网络通信或者后端响应慢,都会增加后端重复处理的概率。
情形

  1. 由于用户误操作,多次点击表单提交按钮。
  2. 由于网速等原因造成页面卡顿,用户重复刷新提交页面。
  3. 黑客或恶意用户使用postman等工具重复恶意提交表单(攻击网站)。
  4. 这些情况都会导致表单重复提交,造成数据重复,增加服务器负载,严重甚至会造成服务器宕机。因此有效防止表单重复提交有一定的必要性。

解决方案:

一:给数据库增加唯一键约束
navicat在这里插入图片描述
这种方法需要在代码中加入捕捉插入数据异常:

 try {// insert} catch (DuplicateKeyException e) {logger.error("user already exist");}
 

二:使用AOP自定义切入实现
实现原理:

1.自定义防止重复提交标记(@AvoidRepeatableCommit)。   
 2.对需要防止重复提交的Congtroller里的mapping方法加上该注解。   
 3.新增Aspect切入点,为@AvoidRepeatableCommit加入切入点。 
 4.每次提交表单时,Aspect都会保存当前key到reids(须设置过期时间)。   
 5.重复提交时Aspect会判断当前redis是否有该key,若有则拦截。
 
/*** 避免重复提交*/@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface AvoidRepeatableCommit {/*** 指定时间内不可重复提交,单位秒* @return*/long timeout()  default 3 ;}
 
/*** 重复提交aop */@Aspect@Componentpublic class AvoidRepeatableCommitAspect {@Autowiredprivate RedisTemplate redisTemplate;/*** @param point*/@Around("@annotation(com.xwolf.boot.annotation.AvoidRepeatableCommit)")public Object around(ProceedingJoinPoint point) throws Throwable {HttpServletRequest request  = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();String ip = IPUtil.getIP(request);//获取注解MethodSignature signature = (MethodSignature) point.getSignature();Method method = signature.getMethod();//目标类、方法String className = method.getDeclaringClass().getName();String name = method.getName();String ipKey = String.format("%s#%s",className,name);int hashCode = Math.abs(ipKey.hashCode());String key = String.format("%s_%d",ip,hashCode);log.info("ipKey={},hashCode={},key={}",ipKey,hashCode,key);AvoidRepeatableCommit avoidRepeatableCommit =  method.getAnnotation(AvoidRepeatableCommit.class);long timeout = avoidRepeatableCommit.timeout();if (timeout < 0){//过期时间5分钟timeout = 60*5;}String value = (String) redisTemplate.opsForValue().get(key);if (StringUtils.isNotBlank(value)){return "请勿重复提交";}redisTemplate.opsForValue().set(key, UUIDUtil.uuid(),timeout,TimeUnit.MILLISECONDS);//执行方法Object object = point.proceed();return object;}}
 

标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。