我们在做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();
}

到此幂等校验就完成了

java实现幂等性校验的更多相关文章

  1. java接口幂等性校验

    关于接口幂等性的概念: 幂等性:同一接口调用多次(使用相同的参数),对系统的影响是相同的. 怎样才是对系统有影响? 有影响--->增删改操作,修改一个用户信息,删除用户与某人的关联关系,生成一个 ...

  2. springboot + redis + 注解 + 拦截器 实现接口幂等性校验

    一.概念 幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次 比如: 订单接口, 不能多次创建订单 支付接口, 重复支付同一笔订单只能扣一次钱 支付宝回调接口, 可能会多 ...

  3. Springboot + redis + 注解 + 拦截器来实现接口幂等性校验

    Springboot + redis + 注解 + 拦截器来实现接口幂等性校验   1. SpringBoot 整合篇 2. 手写一套迷你版HTTP服务器 3. 记住:永远不要在MySQL中使用UTF ...

  4. Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性)

    Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性) 前言:由于前段时间忙于写接口,在接口中需要做很多的参数校验,本着简洁.高效的原则,便写了这个小工具供自己使用(内容 ...

  5. java使用xsd校验xml样例

    知识点:XSD文件是指XML结构定义 ( XML Schemas Definition )文件,是DTD的替代品.可以用一个指定的XML Schema来验证某个XML文档,以检查该XML文档是否符合其 ...

  6. java实现身份证校验

    原文来自:java教程网 题目:身份证校验   身份证校验   如果让你设计个程序,用什么变量保存身份证号码呢?长整数可以吗?不可以!   因为有人的身份证最后一位是"X"   实 ...

  7. java 生成随机校验码

    1 import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.Buffe ...

  8. java 使用注释校验数据有效性

    验证注解 验证的数据类型 说明 空检查 @Null 任意类型 验证注解的元素值是null @NotNull 任意类型 验证注解的元素不是null @NotBlank CharSequence子类型(C ...

  9. java常用正则校验工具类

    正则常用校验工具类 import java.util.regex.Pattern; /** * @program: * @description: 校验工具类 * @author: xujingyan ...

  10. java生成MD5校验码

    在Java中,java.security.MessageDigest (rt.jar中)已经定义了 MD5 的计算,所以我们只需要简单地调用即可得到 MD5 的128 位整数.然后将此 128 位计 ...

随机推荐

  1. 一文看完String的前世今生,内容有点多,请耐心看完!

    写在开头 String字符串作为一种引用类型,在Java中的地位举足轻重,也是代码中出现频率最高的一种数据结构,因此,我们需要像分析Object一样,将String作为一个topic,单独拿出来总结, ...

  2. java基础-反射-day15

    目录 1. 案例引入 2. Class 的理解 3. 反射的详细使用 4. Class 类都有哪些实例 5. 详细使用 6. 获取属性 7. 获取方法 8 获取类的 接口 注解 所在的包 9. 思考 ...

  3. 【MicroPython】生成micropython版本头文件 - py\makeversionhdr.py

    用法 $ python makeversionhdr.py mpversion.h 实现 带git仓 get_version_info_from_git 使用git指令:   git describe ...

  4. mysq-DQL-过滤条件-where

  5. [转帖]Oracle参数解析(parallel_force_local)

    https://www.modb.pro/db/122032 是否需要增加这个参数? 往期专题请查看www.zhaibibei.cn这是一个坚持Oracle,Python,MySQL原创内容的公众号 ...

  6. [转帖]在麒麟linux上安装Postgresql12.5

    https://jimolonely.github.io/tech/linux/install-postgresql-kylin/ 本文主要实践在麒麟V10版本上通过源码编译安装PostgreSQL1 ...

  7. [转帖]分享一个Navicat16最新版永久试用的办法

    https://zhuanlan.zhihu.com/p/614621302 新建bat,就叫 navicat无限试用.bat @echo off echo Delete HKEY_CURRENT_U ...

  8. [转帖]关于Linux操作系统中LUN的队列深度(queue_depth)

    Linux中的queue_depth(队列深度),可以用lsscsi查看. 不过今天在我的vm 虚拟机环境中(无外界存储),是没有lsscsi命令. 不过,从网上,搜到了如下的信息: $ lsscsi ...

  9. [转帖]Linux:页表中PGD、PUD、PMD、TLB等概念介绍

    1.PGD: Page Global Directory        Linux系统中每个进程对应用户空间的pgd是不一样的,但是linux内核 的pgd是一样的.当创建一个新的进程时,都要为新进程 ...

  10. diff算法是如何比较的,保证让你看的明明白白的!

    更新dom节点,最小力度去跟新 index.html <body> <h1>你好啊!</h1> <button id="btn">该 ...