AOP实现防重复提交

为甚么要处理重复提交呢?

   1.  客户端的抖动,用户误操作,网络通信或者服务器响应慢,都有可能会造成服务器重复处理请求。
    2. 为了防止用户重复提交操作,除了从前端控制,后台也需要做控制。
    3. 因为前端的限制不能解决彻底[有时候通过一定的手段可以绕过去]。
    4. 接口实现上,通常要求幂等性,保证多次重复提交只有一次有效。简单说,针对同一笔交易,多次请求它的结果应该是一致的。

实现:

1. 定义防重复提交注解

/**
 * Created with IntelliJ IDEA.
 * @Author: zhaoxn
 * @Date: 2022/11/14/22:43
 * @Description:方法重复提交注解 默认2s内不允许重复调用
 * 也可以支持注解里添加属性,自定义时间间隔,单位(s)
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {
    //超时时间 2s
    long expireSecond() default 2;
}

2. 定义切面逻辑 ,针对加了NoRepeatSubmit注解的方法,做防重复提交判断。

/**
 * Created with IntelliJ IDEA.
 * @Author: zhaoxn
 * @Date: 2022/11/14/22:48
 * @Description:防重复提交切面
 */
@Aspect
@Slf4j
@Component
@Order(-999)
public class NoRepeatSubmitAspect {

    @Autowired
    private RedisTemplate redisTemplate;
    //定义防重复提交key
    public static final String NO_REPEAT_SUBMIT_KEY = "common:noRepeatSubmit:";

    @Around("@annotation(noRepeatSubmit)")
    public Object around(ProceedingJoinPoint pj,NoRepeatSubmit noRepeatSubmit) throws Throwable {
        Object[] args = pj.getArgs();
        String phoneSeries = "3WEPROI2947SDF2340ASDFS4928034"; //这里是假设从args中获取得到客户端送过来的设备唯一标识,实际需要根据场景自定义
        MethodSignature msig = (MethodSignature) pj.getSignature();
        String mName = pj.getTarget().getClass().getMethod(msig.getName(), msig.getParameterTypes()).getName();
        if(StringUtils.isNotEmpty(phoneSeries)){  //这里有可能设备号是空的,比如是三方系统过来的请求
            Boolean hasKey = redisTemplate.hasKey(NO_REPEAT_SUBMIT_KEY + phoneSeries);
            if(null != hasKey && hasKey){
                throw new RuntimeException("您的操作过于频道,请稍等一会!!!");//这里实际应该抛出的是业务异常返给客户端
            }
            redisTemplate.opsForValue().set(NO_REPEAT_SUBMIT_KEY + phoneSeries,"NO_REPEAT_SUBMIT_KEY",noRepeatSubmit.expireSecond(), TimeUnit.SECONDS);
        }else{
            log.warn("当前方法:{}未获取到对应的设备序列号",mName);
        }
        return pj.proceed();
    }
}

3. 完结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Run,boy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值