java 实现简单的防重放方法

  今天分享下我在实际项目中运用的防重放的工具方法,用的是hutool类CacheUtil.newFIFOCache(),也就是FIFOCache缓存限制因用户误操作或网络抖动引起的多次新增或修改问题

maven

<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.4.0</version>
        </dependency>

 

缓存工具类

package com.chinaoly.utils;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.FIFOCache;
import com.chinaoly.utils.config.BizException;

/**
 * 单机缓存锁
 * @author ljh
 * @date 2025/6/16
 **/
public class SingleMachineLock {

    /**
     * FIFOCache ‌是一种基于先进先出(First-In-First-Out,简称FIFO)原则的缓存淘汰策略。当缓存达到容量限制并需要淘汰元素时,最先进入缓存的元素会被移除,以便为新元素腾出空间
     */
    private static final FIFOCache<String, String> CACHE = CacheUtil.newFIFOCache(2048);

    /**
     * 请求控制
     */
    public static void reqControl(String key, long millisecond, String msg) {
        //如果已经加锁则抛出异常
        if (!lockTime(key, millisecond)) {
            BizException.throwException(msg);
        }
    }

    /**
     * 缓存并设置超时时间
     */
    public static boolean lockTime(String key, long milliSend) {
        if (!CACHE.containsKey(key)) {
            //类似于redis的zSet类型(key, value, 分数)
            CACHE.put(key, "", milliSend);
            return true;
        }
        return false;
    }

}

 

抛异常方法类(主要是工具类用到了里面的抛异常方法)

package com.chinaoly.utils.config;

import com.chinaoly.enums.ResultCode;
import lombok.Data;

/**
 * 主动异常抛出
 *
 * @author ljh
 * @date 2021/5/28
 */
@Data
public class BizException extends RuntimeException {

    private ResultCode resultCode = ResultCode.ERROR;

    private BizException(String message) {
        super(message);
    }

    private BizException(ResultCode resultCode, String message) {
        super(message);
        this.resultCode = resultCode;
    }

    /**
     * 抛异常
     */
    public static void throwException(String message) {
        throw new BizException(message);
    }

    public static void throwException(ResultCode resultCode, String message) {
        throw new BizException(resultCode, message);
    }

}

测试api

@PostMapping("/addTest")
    @ApiOperation(value = "addTest",notes = "添加测试表")
    public ResultInfo addTest() {
        //获取用户信息
        ShiroUser user = getUser();
        if (EmptyUtils.isEmpty(user) || EmptyUtils.isEmpty(user.getId())) {
            BizException.throwException("用户不存在");
        }
        //设置不允许重复新增2秒(这里的key采用的是方法名+用户id来保证唯一性)
        SingleMachineLock.reqControl("addTest_"+user.getId(), 2000, "添加测试表中,请勿重复点击");
        return ResultInfo.success("ok");
    }

当然这里代码中有些方法需要替换成你自己本地的方法

 

posted @ 2025-06-17 14:52  马革皮  阅读(41)  评论(0)    收藏  举报