SpringBoot结合Redis实现幂等
1、相关概念和思路
- 幂等:就是说客户端不管访问多少次,服务器端处理或者返回的结果都是一样
- 思路:我们首先让客户端访问一个获取token的接口,然后让客户端携带token来访问具有幂等(@Idempotent)注解的接口,从而消费掉这个token,这样就可以避免用户重复访问一个接口了,我们把token存在redis中并且设置好过期时间。
2、项目依赖和配置
这里没有用到数据库,只是使用spring-web和redis两个依赖,配置也就是配置redis相关
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring.redis.host=localhost
spring.redis.port=6379
3、幂等注解(@Idempotent)
注解起一个标识的作用,我们还需要使用拦截器用来拦截方法,然后通过方法对象获取到方法上面的注解,
我们判断这个注解是否是我们需要的,如果是,则执行相关操作就可以了,不是,直接放行。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {
}
4、拦截器
- 实现HandlerInterceptor接口,加上注解@Component交给spring管理
@Component
public class IdempotentInterceptor implements HandlerInterceptor {
// 注解的作用就是起一个标识的作用,使用拦截器可以拦截方法,然后方法可以获取到注解,判断注解上的方法是否是我们想要的注解,
// 是:执行我们需要的逻辑;不是:注解放行或者拦截
@Autowired
private TokenService tokenService;
//预处理回调方法,实现处理器的预处理(如检查登陆),第三个参数为响应的处理器,自定义Controller的方法对象
//返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),
// 不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,