防止重复提交

自定义重复提交标记

  1. 自定义重复提交注解(NoRepeatSubmit)
  2. 对于防止重复提交的Controllor里的方法加上注解
  3. 新增Aspect切入点,为NoRepeatSubmit加入切入点
  4. 每次提交表单时,aspect都会保存当前的Key到Redis
  5. 重新提交时aspect会判断当前的redis是否有该key,若有则拦截
BaseRepeatSubmitAop.java
@Slf4j
@Aspect
@Component
public class BaseRepeatSubmitAop {
    @Autowired
    private RedisCacheUtil redisCacheUtil;
    @Autowired
    private LoginUserApi loginUserApi;

    final static String REPEAT_KEY = "CACHE:REPEAT:";

    @Around("@annotation(noRepeatSubmit)")
    public Object around(ProceedingJoinPoint point, NoRepeatSubmit noRepeatSubmit) throws Throwable {
        //获取注解
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        String className = method.getDeclaringClass().getName();
        String methodName = method.getName();

        //组装key  用户唯一标识+操作类+方法
        String currentTenantId = loginUserApi.getCurrentTenantId();
        String key = REPEAT_KEY + currentTenantId + "_" + className + "_" + methodName;
        int keyHashCode = Math.abs(key.hashCode());
        log.info("key:{},keyHashCode:{}", key, keyHashCode);

        int timeOut = noRepeatSubmit.timeout();
        log.info("超时时间:{}", timeOut);

        Object value = redisCacheUtil.get(key);

        if (value != null) {
            throw new BusinessException("提交间隔不得超过"+timeOut+"秒!");
        }

        redisCacheUtil.set(key, keyHashCode, timeOut);

        Object object = point.proceed();

        return object;
    }
}

  

@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {

    /**
     * 指定时间内不能重复提交(单位:秒)
     *
     * @return
     */
    int timeout() default 1;
}

 

posted @ 2022-02-14 12:58  蔡徐坤1987  阅读(99)  评论(0编辑  收藏  举报