SpringBoot 3.0使用自定义注解+Interceptor+Redis实现幂等

我们以评论系统为例: 要实现这个需求,你可以按照以下步骤来完成。我们将实现一个自定义注解、一个拦截器、以及在Redis中存储和更新幂等性计数。

步骤1:添加必要的依赖

确保在你的 pom.xml 文件中包含 Spring Boot 和 Redis 的依赖:

 

xml

代码解读

复制代码

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>

步骤2:定义自定义注解

创建一个自定义注解,用于标记需要进行幂等性检查的Controller方法:

 

java

代码解读

复制代码

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) public @interface Idempotent { long expireTime() default 60; // 默认过期时间,单位:秒 }

步骤3:创建幂等性检查的拦截器

创建一个拦截器,拦截带有 @Idempotent 注解的方法,并进行幂等性检查:

 

java

代码解读

复制代码

import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; import java.security.Principal; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; @Component public class IdempotencyInterceptor implements HandlerInterceptor { @Autowired private StringRedisTemplate redisTemplate; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); Idempotent idempotent = method.getAnnotation(Idempotent.class); if (idempotent != null) { // 获取当前用户ID Principal principal = request.getUserPrincipal(); String username = principal.getName(); // 或从SecurityContext中获取 String comment = request.getParameter("comment"); // 生成Redis的Key String key = "idempotent:" + username + ":" + comment; Long expireTime = idempotent.expireTime(); // 检查Redis中是否存在 String value = redisTemplate.opsForValue().get(key); if (value == null) { // 不存在,存入Redis redisTemplate.opsForValue().set(key, "1", expireTime, TimeUnit.SECONDS); } else { // 存在,进行计数 int count = Integer.parseInt(value); if (count >= 3) { // 超过次数限制 response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.getWriter().write("重复评论已达到上限"); return false; } else { redisTemplate.opsForValue().increment(key); } } } } return true; } }

步骤4:注册拦截器

在配置类中注册这个拦截器:

 

java

代码解读

复制代码

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private IdempotencyInterceptor idempotencyInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(idempotencyInterceptor).addPathPatterns("/**"); } }

步骤5:在Controller方法���使用自定义注解

最后,在需要幂等性检查的方法上使用 @Idempotent 注解:

 

java

代码解读

复制代码

import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/comments") public class CommentController { @PostMapping @Idempotent(expireTime = 60) public String addComment(@RequestBody CommentRequest commentRequest) { // 处理添加评论的逻辑 return "评论添加成功"; } }

总结

通过上述步骤,我们创建了一个自定义注解 @Idempotent,一个拦截器 IdempotencyInterceptor,并在拦截器中使用Redis进行幂等性检查。最后在需要检查幂等性的Controller方法上添加该注解即可实现功能

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值