Java 使用 Redis 实现接口幂等性 - 防止重复提交
在 Java 中使用 Redis 实现接口幂等可以通过以下步骤实现:
-
定义一个接口幂等的注解,如 'Idempotent',用于标记需要幂等处理的接口方法。
-
在方法执行前,先从 Redis 中查询是否存在相同的请求,如果存在,则说明该请求已经处理过,直接返回结果,否则继续执行接口方法。
-
在接口方法执行完成后,将请求的唯一标识存储到 Redis 中,并设置过期时间,以确保在一定时间后能够再次处理相同的请求。
以下是一个简单的实现示例:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {
String value() default '';
}
@Component
public class IdempotentInterceptor implements HandlerInterceptor {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Idempotent idempotent = ((HandlerMethod) handler).getMethodAnnotation(Idempotent.class);
if (idempotent == null) {
return true;
}
String key = 'idempotent:' + idempotent.value() + ':' + request.getHeader('token');
if (redisTemplate.hasKey(key)) {
throw new RuntimeException('请勿重复提交');
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
Idempotent idempotent = ((HandlerMethod) handler).getMethodAnnotation(Idempotent.class);
if (idempotent == null) {
return;
}
String key = 'idempotent:' + idempotent.value() + ':' + request.getHeader('token');
redisTemplate.opsForValue().set(key, 1, 60, TimeUnit.SECONDS);
}
}
@RestController
public class TestController {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@RequestMapping('/test')
@Idempotent('test')
public String test() {
return 'success';
}
}
在上述示例中,首先定义了 'Idempotent' 注解,用于标记需要幂等处理的接口方法。然后通过 IdempotentInterceptor 拦截器,在方法执行前从 Redis 中查询是否存在相同的请求,如果存在,则抛出异常,否则继续执行接口方法。在方法执行完成后,将请求的唯一标识存储到 Redis 中,并设置过期时间。最后,在 Controller 中使用 'Idempotent' 注解标记需要幂等处理的接口方法。
原文地址: https://www.cveoy.top/t/topic/mT6g 著作权归作者所有。请勿转载和采集!