Java实现幂等性校验的示例代码

 更新时间:2024年02月18日 11:25:40   作者:名一  
我们在做web应用的时候通常会遇到前端提交按钮重复点击的场景,在某些新增操作上就需要做幂等性限制来保证数据的可靠性,所以本文主要介绍了如何使用java aop实现幂等性校验,需要的可以参考下

我们在做web应用的时候通常会遇到前端提交按钮重复点击的场景,在某些新增操作上就需要做幂等性限制来保证数据的可靠性。下面来用java aop实现幂等性校验。

一:首先我们需要一个自定义注解

package com.yuku.yuku_erp.annotation;

import java.lang.annotation.*;

/**
 * @author 名一
 * @ClassName IdempotentAnnotation
 * @description: 用来标记需要校验幂等性的接口
 * @datetime 2024年 02月 03日 14:48
 * @version: 1.0
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IdempotentAnnotation {
    String idempotentType();
}

二:创建一个幂等校验的切面类

package com.yuku.yuku_erp.aop;

import com.yuku.yuku_erp.annotation.IdempotentAnnotation;
import com.yuku.yuku_erp.constant.RedisKeyConstant;
import com.yuku.yuku_erp.exception.MyException;
import com.yuku.yuku_erp.utils.RedisShardedPoolUtil;
import com.yuku.yuku_erp.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
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.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author 名一
 * @ClassName CheckIdempotentAop
 * @description: 幂等性校验
 * @datetime 2024年 02月 03日 14:59
 * @version: 1.0
 */
@Slf4j
@Aspect
@Component
public class CheckIdempotentAop {

    @Pointcut("execution(* com.yuku.yuku_erp.controller..*.*(..))")
    public void checkCut(){
    }

    @Before("checkCut()")
    public void checkIdempotent(JoinPoint joinPoint){
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        if (method.isAnnotationPresent(IdempotentAnnotation.class)){
            IdempotentAnnotation annotation = method.getAnnotation(IdempotentAnnotation.class);
            String idempotentType = annotation.idempotentType();
            String idempotentToken = TokenUtil.getRequest().getHeader("idempotentToken");
            String idemToken = idempotentType + idempotentToken;
            log.info("checkIdempotent idempotentType:{}, idempotentToken:{}", idempotentType, idempotentToken);

            Boolean flag = RedisShardedPoolUtil.sismember(RedisKeyConstant.IDEMPOTENT_TOKEN_LIST, idemToken);
            if (!flag){
                log.error("checkIdempotent error idempotentType:{}, idempotentToken:{}, flag:{}", idempotentType, idempotentToken, flag);
                throw new MyException("该接口已提交过,请不要重复提交");
            }
            RedisShardedPoolUtil.delSetByValue(RedisKeyConstant.IDEMPOTENT_TOKEN_LIST, idemToken);
            log.info("checkIdempotent idempotentType:{}, idempotentToken:{}, flag:{}", idempotentType, idempotentToken, flag);
        }
    }
}

三:在需要切面的接口上使用幂等校验注解

@IdempotentAnnotation(idempotentType = "checkIdempotentToken")
    @GetMapping("/checkIdempotentToken")
    @ApiOperation(value = "校验幂等性示例")
    public CommonResult<String> checkIdempotentToken(){
        return CommonResult.success();
    }

到此幂等校验就完成了

四:方法补充

除了上文的方法,小编还为大家整理了其他实现幂等校验的方法,希望对大家有所帮助

1.唯一标识符校验

一种简单的方式是使用唯一标识符来校验请求的幂等性,每次请求时,客户端生成一个唯一的标识符,并将其作为请求的一部分发送给服务器。服务器在接收到请求后先检查该标识符是否已经存在,如果存在则认为是重复请求,直接忽略;如果不存在,则执行相应的业务逻辑,并将标识符保存到一个幂等性校验表中

下面是一个使用 UUID 实现的示例代码:

// 生成唯一标识符
String requestId = UUID.randomUUID().toString();

// 发送清求
HttpResponse response = httpClient.execute(request);

// 检查响应结果
if (response.getStatusLine().getStatusCode() == 200){
    // 保存标识符到幂等性校验表
    idempotentTable.put(requestId, true);
}

2. Token 校验

另一种方式是使用 Token 来校验请求的幂等性。服务器在第一次收到请求时,在响应中返回一个唯一的 Token 给客户端,客户端在下次请求时将该 Token 作为请求的一部分发送给服务器。服务器在接收到请求后,先检查该 Token 是否有效,如果有效则执行相应的业务逻辑,并将 Token 标记为已使用;如果无效则忽略该请求。

下面是一个使用 Token 实现的示例代码:

// 发送第一次诗求,并获 Token
HttpResponse response1 = httpClient.execute(request);
String token = response1.getFirstHeader("Token").getValue();

// 发送第二次诗求,并附 Token
request.addHeader("Token",token);
HttpResponse response2 = httpClient.execute(request);

// 检查响应结果
if (response2.getStatusLine().getstatusCode() == 200) {
    // 标记 Token 为已使用
    tokenService.markAsUsed(token);
}

到此这篇关于Java实现幂等性校验的示例代码的文章就介绍到这了,更多相关Java幂等性校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何解决项目中java heap space的问题

    如何解决项目中java heap space的问题

    这篇文章主要介绍了如何解决项目中java heap space的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Java类初始化执行流程解析

    Java类初始化执行流程解析

    这篇文章主要介绍了Java类初始化执行流程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05
  • SpringBoot与Angular2的集成示例

    SpringBoot与Angular2的集成示例

    本篇文章主要介绍了SpringBoot与Angular2的集成示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • java随机数生成具体实现代码

    java随机数生成具体实现代码

    这篇文章主要为大家分享了java随机数生成具体实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • SpringBoot接受前台参数的6种方式以及统一响应代码示例

    SpringBoot接受前台参数的6种方式以及统一响应代码示例

    这篇文章主要给大家介绍了关于SpringBoot接受前台参数的6种方式以及统一响应的相关资料,前端负责展示页面和用户交互,而后端则负责处理业务逻辑和数据存储,在这种架构下前端需要将用户输入的数据发送给后端进行处理,需要的朋友可以参考下
    2023-12-12
  • springBoot详解集成Swagger流程

    springBoot详解集成Swagger流程

    Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化 Restful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法、参数和模型紧密集成到服务器端的代码,允许API来始终保持同步
    2022-06-06
  • Java中HttpServletResponse响应中文出现乱码问题

    Java中HttpServletResponse响应中文出现乱码问题

    这篇文章主要介绍了Java中HttpServletResponse响应中文出现乱码问题的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • java实现简单日期计算功能

    java实现简单日期计算功能

    这篇文章主要为大家详细介绍了java实现简单日期计算功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • java版简单的猜数字游戏实例代码

    java版简单的猜数字游戏实例代码

    猜数字游戏是一款经典的游戏,该游戏说简单也很简单,说不简单确实也很难,那么下面这篇文章主要给大家介绍了java版简单的猜数字游戏的相关资料,文中给出了详细的实现分析和示例代码供大家参考学习,需要的朋友们下面来一起看看吧。
    2017-05-05
  • Spring Boot日志收集及链路追踪实现示例

    Spring Boot日志收集及链路追踪实现示例

    这篇文章主要为大家介绍了Spring Boot日志收集及链路追踪实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12

最新评论