首页 > 数据库 >Redisson幂等校验例子

Redisson幂等校验例子

时间:2023-08-28 12:44:39浏览次数:43  
标签:lang Redisson java 校验 aspectj 例子 org import annotation

在添加接口增加幂等校验, 防止用户在短时间内重复调用添加接口

import org.apache.commons.lang3.ArrayUtils;
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.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
@Order(1)
public class IdempotentAspect {
@Autowired
private RedissonClient redissonClient;
@Pointcut("@annotation(com.aexpec.cmd.common.annotation.IdempotentCheck)")
public void idempotentCheck() {
}

@Before("idempotentCheck()")
public void doBefore(JoinPoint joinPoint) {
//拿到被注解的方法签名
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//拿到被注解的方法
Method method = signature.getMethod();
Object[] args = joinPoint.getArgs();
Method targetMethod = AopUtils.getMostSpecificMethod(method, joinPoint.getTarget().getClass());
IdempotentCheck idempotentCheck = AnnotationUtils.findAnnotation(targetMethod, IdempotentCheck.class);
if (null == idempotentCheck) {
throw new BizException(BaseCode.PARAM_ERROR);
}
int expireTime = idempotentCheck.expireTime();
StringBuilder key = new StringBuilder(targetMethod.getName())
.append(targetMethod.getName())
.append(ArrayUtils.toString(args, "-"));
RBucket<Object> bucket = redissonClient.getBucket(key.toString());
if (bucket.isExists()) {
throw new BizException(BaseCode.NOT_REPEAT_COMMIT);
} else {
bucket.set(AuthUtil.getUserInfo().getUserAccount(), expireTime, TimeUnit.SECONDS);
}
}
}

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IdempotentCheck {
int expireTime() default 3;
}
@RestController
@RequestMapping("/a")
public class AController {
  @PostMapping("/{modelCode}/add")
  @IdempotentCheck()
  public ApiResponse<String> add(
@PathVariable("modelCode") String modelCode,
@RequestBody Map<String, Object> params) {
  // ...
  return new ApiResponse<String>().success();
  }
}

标签:lang,Redisson,java,校验,aspectj,例子,org,import,annotation
From: https://www.cnblogs.com/ladeng19/p/15716435.html

相关文章

  • C# 验证码的简单生成,登录实现校验验证码
    登录实现校验验证码1、思路:首先写一个生成验证码的接口,接口传出就是验证码的唯一id和验证码图片的base64,把验证码的id当做缓存的key,再把生成的验证码code当做值存到缓存中。2、登录:输入用户名、密码、验证码唯一id和用户输入的验证码值。用验证码唯一id获取到缓存中的验证码值,......
  • Vue element 表单验证不通过时,滚动到校验未通过位置
    我们在使用elementIUI实现表单验证,内容比较多的时候,提示内容会被遮挡,这时候用户不清楚什么情况,还会连续点击提交按钮。这个时候需求来啦:我们需要在表单验证不通过的时候,页面滚动到对应校验不通过的位置。大致思路在表单验证方法validate中,提供了两个参数:是否校验成功,和未通过校......
  • Struts2输入校验以及错误信息处理(2)——用Struts2定义好的校验框架进行校验
    Struts2的输入校验有两种方式:一种是用Action中定义的validate()方法进行校验,一种是用Struts2定义好的校验框架进行校验。前者里面的逻辑判断要自己写,而后者只需要传递相应的参数即可。不管是哪种方式,程序执行的流程都是一样的,执行流程如下:1、对表单传递过来的数据,先进行类型转换......
  • Struts2的自定义类型转换和简单的输入校验
    这里关键是对自定义类型的理解,它和8个基本数据类型的地位是一样的,只不过这个是你自己定义的类型。那么在Struts2中什么时候要用到数据类型转换呢?其实,我们一直在用,只是我们没有感觉到而已,Struts2对8个基本数据类型以及Date、String等常见类型,会自动的用内建的类型转换器进行转换,这个......
  • Struts2输入校验以及错误信息处理(1)——用Action中定义的validate()方法进行校验
    Struts2的输入校验有两种方式:一种是用Action中定义的validate()方法进行校验,一种是用Struts2定义好的校验框架进行校验。前者里面的逻辑判断要自己写,而后者只需要传递相应的参数即可。不管是哪种方式,程序执行的流程都是一样的,执行流程如下:1、对表单传递过来的数据,先进行类型转换2、......
  • 【MySQL 8.0】通过pt-table-checksum校验从库与主库的数据一致性
    通过yum安装percona-toolkit[root@node01~]#wgethttps://repo.percona.com/yum/percona-release-latest.noarch.rpm[root@node01~]#rpm-ivhpercona-release-latest.noarch.rpm[root@node01~]#yuminstall-ypercona-toolkit[mysql@node01~]$pt-table-checksum--......
  • c++ stl std::sort使用例子
    classUser{public:int32_tm_fight_power;private:int32_tm_level;};boolCenterData::compare(constUser*left,constUser*right){if(left->m_fight_power!=right->m_fight_power){returnleft->m_fight_power>ri......
  • Android NDK基础介绍及例子
    目录nullNDK介绍java调用c的步骤一、NDK/JNINDKJNI-那么为什么需要在Android上去使用C/C++代码?NDK开发新建一个Native项目设置调试模式编写编译脚本文件CMakeLists.txt加载C/C++库(1)加载APK中的C/C++库文件(2)加载外部的C/C++so库实现Java和C++互相调用生成so文件参考Android开发......
  • 关于公用方法的参数校验和异常抛出
    通常来说,比较规范的写法和定义:1、公用方法,尤其是业务上的公用方法是不做参数校验的,由调用方校验参数,因为公用方法通常简短且正确性要有保障,导致出错的原因通常是外部导致的,所以参数校验和日志的打印由调用方去写。2、公用方法对于参数进行操作以后,那么还是会打印一些日志的,比如......
  • 参数校验和分组
    对于参数校验的一个总结意义:前端校验了,后端也进行数据校验,保存数据安全性/****@Description**JSR提供的校验注解:**@Null被注释的元素必须为null*@NotNull被注释的元素必须不为null*@AssertTrue被注释的元素必须为true*@AssertFalse被注释的元素......