2

今天用AI搞一个防止接口重复提交注解

 11 months ago
source link: https://www.51cto.com/article/756691.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

今天用AI搞一个防止接口重复提交注解

作者:了不起 2023-06-05 08:22:20
接口幂等性是指无论调用接口的次数是一次还是多次,对于同一资源的操作都只会产生一次结果。换句话说,多次重复调用相同的接口请求应该具有与单次请求相同的效果,不会导致不一致或副作用的发生。

哈喽,大家好,我是了不起。

接口幂等性是指无论调用接口的次数是一次还是多次,对于同一资源的操作都只会产生一次结果。换句话说,多次重复调用相同的接口请求应该具有与单次请求相同的效果,不会导致不一致或副作用的发生。

今天我们使用AI帮我们去创建一个自定义注解,可以防止接口30秒内的重复请求,并采用Redis作为缓存。

话不多说,直接提问:

图片

等待数分钟后。。。

1.创建自定义注解 其中包括接口保护时长,开启防止重复提交保护等。

图片

2.然后创建拦截器

图片

这里我们贴出拦截器的核心代码:

@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            RepeatSubmit annotation = handlerMethod.getMethodAnnotation(RepeatSubmit.class);
            if (annotation != null && annotation.enable()) {
                String key = buildKey(request);
                if (StringUtils.hasText(redisTemplate.opsForValue().get(key))) {
                    response.getWriter().write("repeat request, please try again later!");
                    return false;
                } else {
                    redisTemplate.opsForValue().set(key, Arrays.toString(request.getInputStream().readAllBytes()), annotation.timeout(), TimeUnit.SECONDS);
                }
            }
        }
        return true;
    }
 //创建redis 缓存key
    private String buildKey(HttpServletRequest request) throws IOException, NoSuchAlgorithmException {
        String key = useRequestMD5 ? hashRequest(request) : request.getRequestURI();
        return "repeat-submit:" + key;
    }

 //对请求做hash运算
    private String hashRequest(HttpServletRequest request) throws IOException, NoSuchAlgorithmException {
        byte[] hashBytes = MessageDigest.getInstance("MD5").digest(request.getInputStream().readAllBytes());
        StringBuilder sb = new StringBuilder();
        for (byte b : hashBytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

3.注册拦截器

图片

最后给出的解释与使用方法。

图片

上面就是最关键的代码了。

接入Redis

下面我们接入Redis。最精简的配置版本:

spring:
  data:
    redis:
      host: 127.0.0.1 
      port: 6379

接口使用注解

@RestController
public class RepeatTestController {

    @RepeatSubmit
    @GetMapping("/hello/mono1")
    public Mono<String> mono(){
        return Mono.just("Hello Mono -  Java North");
    }

    @RepeatSubmit
    @PostMapping ("/hello/mono1")
    public Mono<String> mono1(@RequestBody User user){
        return Mono.just("Hello Mono -  Java North-"+user.getName());
    }
}

本地起一个Redis,然后启动本地的SpringBoot项目进行测试。

图片

本地接口测试:30秒内重复请求会需要直接被拦截

图片

Redis中缓存的KEY如下:

图片

以上就是利用AI为我们生成的一个简单的接口短时间内防止重复提交的注解代码!

相关代码在文章末尾,需要的话可以白嫖哈!

接口幂等性解决方案

下面问一下接口幂等性解决方案,

图片

关于这个回答,大家觉得怎么样?

相关代码链接,欢迎来嫖:

https://github.com/javatechnorth/java-study-note/tree/master/isv-repeat-submit-spring-boot-starter


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK