• java实现幂等性校验


    我们在做web应用的时候通常会遇到前端提交按钮重复点击的场景,在某些新增操作上就需要做幂等性限制来保证数据的可靠性。下面来用java aop实现幂等性校验。

    一:首先我们需要一个自定义注解

    复制代码
    package com.yuku.yuku_erp.annotation;
    
    import java.lang.annotation.*;
    
    /**
     * @author 名一
     * @ClassName IdempotentAnnotation
     * @description: 用来标记需要校验幂等性的接口
     * @datetime 2024年 02月 03日 14:48
     * @version: 1.0
     */
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface IdempotentAnnotation {
        String idempotentType();
    }
    复制代码

    二:创建一个幂等校验的切面类

    复制代码
    package com.yuku.yuku_erp.aop;
    
    import com.yuku.yuku_erp.annotation.IdempotentAnnotation;
    import com.yuku.yuku_erp.constant.RedisKeyConstant;
    import com.yuku.yuku_erp.exception.MyException;
    import com.yuku.yuku_erp.utils.RedisShardedPoolUtil;
    import com.yuku.yuku_erp.utils.TokenUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.stereotype.Component;
    
    import java.lang.reflect.Method;
    
    /**
     * @author 名一
     * @ClassName CheckIdempotentAop
     * @description: 幂等性校验
     * @datetime 2024年 02月 03日 14:59
     * @version: 1.0
     */
    @Slf4j
    @Aspect
    @Component
    public class CheckIdempotentAop {
    
        @Pointcut("execution(* com.yuku.yuku_erp.controller..*.*(..))")
        public void checkCut(){
        }
    
        @Before("checkCut()")
        public void checkIdempotent(JoinPoint joinPoint){
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            if (method.isAnnotationPresent(IdempotentAnnotation.class)){
                IdempotentAnnotation annotation = method.getAnnotation(IdempotentAnnotation.class);
                String idempotentType = annotation.idempotentType();
                String idempotentToken = TokenUtil.getRequest().getHeader("idempotentToken");
                String idemToken = idempotentType + idempotentToken;
                log.info("checkIdempotent idempotentType:{}, idempotentToken:{}", idempotentType, idempotentToken);
    
                Boolean flag = RedisShardedPoolUtil.sismember(RedisKeyConstant.IDEMPOTENT_TOKEN_LIST, idemToken);
                if (!flag){
                    log.error("checkIdempotent error idempotentType:{}, idempotentToken:{}, flag:{}", idempotentType, idempotentToken, flag);
                    throw new MyException("该接口已提交过,请不要重复提交");
                }
                RedisShardedPoolUtil.delSetByValue(RedisKeyConstant.IDEMPOTENT_TOKEN_LIST, idemToken);
                log.info("checkIdempotent idempotentType:{}, idempotentToken:{}, flag:{}", idempotentType, idempotentToken, flag);
            }
        }
    }
    复制代码

    三:在需要切面的接口上使用幂等校验注解

    复制代码
    @IdempotentAnnotation(idempotentType = "checkIdempotentToken")
        @GetMapping("/checkIdempotentToken")
        @ApiOperation(value = "校验幂等性示例")
        public CommonResult checkIdempotentToken(){
            return CommonResult.success();
        }
    复制代码

    到此幂等校验就完成了

     

  • 相关阅读:
    5. HTTPS的特点
    DPVS的定时器
    包装机(栈和队列的应用)
    HTML、JavaScript连接MySQL数据库以及对数据库的表进行修改
    win10+cuda10.2+cudnn10.2+anaconda3+paddle-ocr
    Deno vs. Bun vs. Node.js功能比较
    基于BP神经网络的电力负荷预测附Matlab代码
    算法:O(1) 时间插入、删除和获取随机元素---哈希表+动态数组
    Hadoop大数据应用:HDFS 集群节点扩容
    tap栏切换(固定位置型)
  • 原文地址:https://www.cnblogs.com/mingyi-wang/p/18018873