千家信息网

springboot幂等切片怎么实现

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,本篇内容介绍了"springboot幂等切片怎么实现"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一
千家信息网最后更新 2025年01月19日springboot幂等切片怎么实现

本篇内容介绍了"springboot幂等切片怎么实现"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、前言

最近测试提某些接口重复提交的问题,想了下应该不止是前端点击之后按钮不可点击的问题,后端应该根据登录token、操作方法、参数做多层的判断。

二、示例

切片代码

/** * 接口幂等切面 * @author Administrator */@Slf4j@Aspect@Componentpublic class ApiIdempotentAspect {    @Resource    RedisUtil redisUtil;    @Resource    UserUtils userUtils;    @Pointcut("@annotation(com.xx.anno.ApiIdempotent)")    private void pointCut() {    }    @Before("pointCut()")    public void doPoint(JoinPoint joinPoint) {        String action = joinPoint.getSignature().getDeclaringTypeName()                .substring(joinPoint.getSignature().getDeclaringTypeName().lastIndexOf(".")+1)                + "::" + joinPoint.getSignature().getName();        String args = JSON.toJSONString(joinPoint.getArgs());        String token = userUtils.getAuthToke().replace("-","")                .replace("Bearer ","");        String idempotentKey = "api::idempotent::"+token+"::"+action;        //短时间内没进行相似操作        if(redisUtil.hasKey(idempotentKey)){            //接口参数是否一致            String idempotentValue = redisUtil.getCacheObject(idempotentKey);            log.info("idempotentValue : {}",idempotentValue);            if(args.equals(idempotentValue)){                throw new BusinessException("请勿重复操作");            }        } else{            //30s内禁止重复操作            redisUtil.setCacheObject(idempotentKey,args,30, TimeUnit.SECONDS);        }    }}

用到一个redisutil

@Componentpublic class RedisUtil {    @Resource    public RedisTemplate redisTemplate;    /**     * 缓存基本的对象,Integer、String、实体类等     *     * @param key 缓存的键值     * @param value 缓存的值     */    public  void setCacheObject(final String key, final T value)    {        redisTemplate.opsForValue().set(key, value);    }    /**     * 缓存基本的对象,Integer、String、实体类等     *     * @param key 缓存的键值     * @param value 缓存的值     * @param timeout 时间     * @param timeUnit 时间颗粒度     */    public  void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)    {        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);    }    /**     * 设置有效时间     *     * @param key Redis键     * @param timeout 超时时间     * @return true=设置成功;false=设置失败     */    public boolean expire(final String key, final long timeout)    {        return expire(key, timeout, TimeUnit.SECONDS);    }    /**     * 设置有效时间     *     * @param key Redis键     * @param timeout 超时时间     * @param unit 时间单位     * @return true=设置成功;false=设置失败     */    public boolean expire(final String key, final long timeout, final TimeUnit unit)    {        return redisTemplate.expire(key, timeout, unit);    }    /**     * 获得缓存的基本对象。     *     * @param key 缓存键值     * @return 缓存键值对应的数据     */    public  T getCacheObject(final String key)    {        ValueOperations operation = redisTemplate.opsForValue();        return operation.get(key);    }    /**     * 删除单个对象     *     * @param key     */    public boolean deleteObject(final String key)    {        return redisTemplate.delete(key);    }    /**     * 删除集合对象     *     * @param collection 多个对象     * @return     */    public long deleteObject(final Collection collection)    {        return redisTemplate.delete(collection);    }    /**     * 缓存List数据     *     * @param key 缓存的键值     * @param dataList 待缓存的List数据     * @return 缓存的对象     */    public  long setCacheList(final String key, final List dataList)    {        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);        return count == null ? 0 : count;    }    /**     * 获得缓存的list对象     *     * @param key 缓存的键值     * @return 缓存键值对应的数据     */    public  List getCacheList(final String key)    {        return redisTemplate.opsForList().range(key, 0, -1);    }    /**     * 缓存Set     *     * @param key 缓存键值     * @param dataSet 缓存的数据     * @return 缓存数据的对象     */    public  BoundSetOperations setCacheSet(final String key, final Set dataSet)    {        BoundSetOperations setOperation = redisTemplate.boundSetOps(key);        Iterator it = dataSet.iterator();        while (it.hasNext())        {            setOperation.add(it.next());        }        return setOperation;    }    /**     * 获得缓存的set     *     * @param key     * @return     */    public  Set getCacheSet(final String key)    {        return redisTemplate.opsForSet().members(key);    }    /**     * 缓存Map     *     * @param key     * @param dataMap     */    public  void setCacheMap(final String key, final Map dataMap)    {        if (dataMap != null) {            redisTemplate.opsForHash().putAll(key, dataMap);        }    }    /**     * 获得缓存的Map     *     * @param key     * @return     */    public  Map getCacheMap(final String key)    {        return redisTemplate.opsForHash().entries(key);    }    /**     * 往Hash中存入数据     *     * @param key Redis键     * @param hKey Hash键     * @param value 值     */    public  void setCacheMapValue(final String key, final String hKey, final T value)    {        redisTemplate.opsForHash().put(key, hKey, value);    }    /**     * 获取Hash中的数据     *     * @param key Redis键     * @param hKey Hash键     * @return Hash中的对象     */    public  T getCacheMapValue(final String key, final String hKey)    {        HashOperations opsForHash = redisTemplate.opsForHash();        return opsForHash.get(key, hKey);    }    /**     * 获取多个Hash中的数据     *     * @param key Redis键     * @param hKeys Hash键集合     * @return Hash对象集合     */    public  List getMultiCacheMapValue(final String key, final Collection hKeys)    {        return redisTemplate.opsForHash().multiGet(key, hKeys);    }    /**     * 获得缓存的基本对象列表     *     * @param pattern 字符串前缀     * @return 对象列表     */    public Collection keys(final String pattern)    {        return redisTemplate.keys(pattern);    }    /**     * 判断key是否还在     * @param key     * @return     */    public boolean hasKey(final String key){        return redisTemplate.hasKey(key);    }}

"springboot幂等切片怎么实现"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0