当前位置: 首页 > news >正文

java防抖,防止表单重复提交,aop注解形式

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 AntiShake {
    // 默认过期时间3秒
    int expire() default 3;
}

防抖切面

import jakarta.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;

/**
 * 防抖
 */
@Aspect
@Component
public class AntiShakeAop {

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 切入点
     */
    @Pointcut("@annotation(xx.xx.xx.xx.xx.AntiShake)")
    public void pt() {
    }

    @Around("pt()")
    public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
        StringBuilder sb = new StringBuilder();
        for (Object arg : joinPoint.getArgs()) {
            if (arg != null) {
                sb.append(arg.toString());
            }
        }
        String paramHash = md5(sb.toString());
        String key = "anti-shake:"+ joinPoint.getSignature().getName() + ":" + paramHash;
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        int expire = method.getAnnotation(AntiShake.class).expire();
        // 如果缓存中有这个url视为重复提交
        if (!redisUtil.hasKey(key)) {
            //然后存入redis 并且设置倒计时
            redisUtil.set(key, 0, expire, TimeUnit.SECONDS);
            //返回结果
            return joinPoint.proceed();
        } else {
            throw new RuntimeException("请勿重复提交或者操作过于频繁!");
        }

    }

    private String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : messageDigest) {
                String hex = Integer.toHexString(0xFF & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}

用法

    @AntiShake
    @GetMapping("/test")
    public String test(@RequestParam String name ) throws Exception {
        log.info("防抖测试:{}", name);
        Thread.sleep(10000);
        return "success";
    }

http://www.dtcms.com/a/26059.html

相关文章:

  • deepseek帮我设计物理量采集单片机口保护电路方案
  • 什么是Baklib云内容中台?
  • chrome V3插件开发,调用 chrome.action.setIcon,提示路径找不到
  • 操作系统2.4
  • 虚拟环境下Python调用C++开发的dll如何联调?一文解答!(Python开发环境PyCharm,C++开发环境Visual Studio)
  • Python JSON的深度解析:从基础到应用
  • 【用deepseek实现快递查询】快递物流查询-快递查询-快递查询-快递物流查询-快递物流轨迹查询-快递物流查询接口-快递查询-快递物流查询
  • Flask实现高效日志记录模块
  • DeepSeek与ChatGPT:AI语言模型的全面技术解析与对比
  • linux进程间通信的posix消息队列应用记录
  • Go日期时间处理工具Carbon
  • python 如何获取文件的keys
  • 【C语言】C语言 哈夫曼编码传输(源码+数据文件)【独一无二】
  • 2025年人工智能与教育系统国际学术会议(ICAIES 2025)
  • postgres源码学习之简单sql查询
  • Java开发实习面试笔试题(含答案)
  • 【信息系统项目管理师】专业英语重点词汇大汇总
  • 数字电路中的焊接技术
  • MyBatis XML映射文件中的批量插入和更新
  • 模电知识点总结(2)
  • 信息安全管理体系认证:赋能组织应对数字时代的风险与挑战
  • 【含文档+PPT+源码】基于微信小程序的猎兔汽车保养维修美容服务平台的设计与实现
  • INA219电流、电压、功率测量芯片应用
  • Ollama 本地GUI客户端:为DeepSeek用户量身定制的智能模型管理与交互工具
  • 斐波那契数列模型:在动态规划的丝绸之路上追寻斐波那契的足迹(上)
  • 在VS-qt的程序中,后期增加PCH预编译功能,提高编译速度
  • 【练习】【二分】力扣热题100 34. 在排序数组中查找元素的第一个和最后一个位置
  • 蓝桥杯 Java B 组之设计 LRU 缓存
  • 【DeepSeek系列】04 DeepSeek-R1:带有冷启动的强化学习
  • 吊舱夜视与测距功能:核心技术、应用与未来展望