亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

springboot冪等切片的實(shí)現(xiàn)

 更新時(shí)間:2022年03月01日 15:10:49   作者:_Rondo  
本文主要介紹了springboot冪等切片的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

一、前言

最近測試提某些接口重復(fù)提交的問題,想了下應(yīng)該不止是前端點(diǎn)擊之后按鈕不可點(diǎn)擊的問題,后端應(yīng)該根據(jù)登錄token、操作方法、參數(shù)做多層的判斷。

二、示例

切片代碼

/**
?* 接口冪等切面
?* @author Administrator
?*/
@Slf4j
@Aspect
@Component
public 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;
? ? ? ? //短時(shí)間內(nèi)沒進(jìn)行相似操作
? ? ? ? if(redisUtil.hasKey(idempotentKey)){
? ? ? ? ? ? //接口參數(shù)是否一致
? ? ? ? ? ? String idempotentValue = redisUtil.getCacheObject(idempotentKey);
? ? ? ? ? ? log.info("idempotentValue : {}",idempotentValue);
? ? ? ? ? ? if(args.equals(idempotentValue)){
? ? ? ? ? ? ? ? throw new BusinessException("請(qǐng)勿重復(fù)操作");
? ? ? ? ? ? }
? ? ? ? } else{
? ? ? ? ? ? //30s內(nèi)禁止重復(fù)操作
? ? ? ? ? ? redisUtil.setCacheObject(idempotentKey,args,30, TimeUnit.SECONDS);
? ? ? ? }

? ? }

}

用到一個(gè)redisutil

@Component
public class RedisUtil {

? ? @Resource
? ? public RedisTemplate redisTemplate;

? ? /**
? ? ?* 緩存基本的對(duì)象,Integer、String、實(shí)體類等
? ? ?*
? ? ?* @param key 緩存的鍵值
? ? ?* @param value 緩存的值
? ? ?*/
? ? public <T> void setCacheObject(final String key, final T value)
? ? {
? ? ? ? redisTemplate.opsForValue().set(key, value);
? ? }

? ? /**
? ? ?* 緩存基本的對(duì)象,Integer、String、實(shí)體類等
? ? ?*
? ? ?* @param key 緩存的鍵值
? ? ?* @param value 緩存的值
? ? ?* @param timeout 時(shí)間
? ? ?* @param timeUnit 時(shí)間顆粒度
? ? ?*/
? ? public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
? ? {
? ? ? ? redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
? ? }

? ? /**
? ? ?* 設(shè)置有效時(shí)間
? ? ?*
? ? ?* @param key Redis鍵
? ? ?* @param timeout 超時(shí)時(shí)間
? ? ?* @return true=設(shè)置成功;false=設(shè)置失敗
? ? ?*/
? ? public boolean expire(final String key, final long timeout)
? ? {
? ? ? ? return expire(key, timeout, TimeUnit.SECONDS);
? ? }

? ? /**
? ? ?* 設(shè)置有效時(shí)間
? ? ?*
? ? ?* @param key Redis鍵
? ? ?* @param timeout 超時(shí)時(shí)間
? ? ?* @param unit 時(shí)間單位
? ? ?* @return true=設(shè)置成功;false=設(shè)置失敗
? ? ?*/
? ? public boolean expire(final String key, final long timeout, final TimeUnit unit)
? ? {
? ? ? ? return redisTemplate.expire(key, timeout, unit);
? ? }

? ? /**
? ? ?* 獲得緩存的基本對(duì)象。
? ? ?*
? ? ?* @param key 緩存鍵值
? ? ?* @return 緩存鍵值對(duì)應(yīng)的數(shù)據(jù)
? ? ?*/
? ? public <T> T getCacheObject(final String key)
? ? {
? ? ? ? ValueOperations<String, T> operation = redisTemplate.opsForValue();
? ? ? ? return operation.get(key);
? ? }

? ? /**
? ? ?* 刪除單個(gè)對(duì)象
? ? ?*
? ? ?* @param key
? ? ?*/
? ? public boolean deleteObject(final String key)
? ? {
? ? ? ? return redisTemplate.delete(key);
? ? }

? ? /**
? ? ?* 刪除集合對(duì)象
? ? ?*
? ? ?* @param collection 多個(gè)對(duì)象
? ? ?* @return
? ? ?*/
? ? public long deleteObject(final Collection collection)
? ? {
? ? ? ? return redisTemplate.delete(collection);
? ? }

? ? /**
? ? ?* 緩存List數(shù)據(jù)
? ? ?*
? ? ?* @param key 緩存的鍵值
? ? ?* @param dataList 待緩存的List數(shù)據(jù)
? ? ?* @return 緩存的對(duì)象
? ? ?*/
? ? public <T> long setCacheList(final String key, final List<T> dataList)
? ? {
? ? ? ? Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
? ? ? ? return count == null ? 0 : count;
? ? }

? ? /**
? ? ?* 獲得緩存的list對(duì)象
? ? ?*
? ? ?* @param key 緩存的鍵值
? ? ?* @return 緩存鍵值對(duì)應(yīng)的數(shù)據(jù)
? ? ?*/
? ? public <T> List<T> getCacheList(final String key)
? ? {
? ? ? ? return redisTemplate.opsForList().range(key, 0, -1);
? ? }

? ? /**
? ? ?* 緩存Set
? ? ?*
? ? ?* @param key 緩存鍵值
? ? ?* @param dataSet 緩存的數(shù)據(jù)
? ? ?* @return 緩存數(shù)據(jù)的對(duì)象
? ? ?*/
? ? public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
? ? {
? ? ? ? BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
? ? ? ? Iterator<T> it = dataSet.iterator();
? ? ? ? while (it.hasNext())
? ? ? ? {
? ? ? ? ? ? setOperation.add(it.next());
? ? ? ? }
? ? ? ? return setOperation;
? ? }

? ? /**
? ? ?* 獲得緩存的set
? ? ?*
? ? ?* @param key
? ? ?* @return
? ? ?*/
? ? public <T> Set<T> getCacheSet(final String key)
? ? {
? ? ? ? return redisTemplate.opsForSet().members(key);
? ? }

? ? /**
? ? ?* 緩存Map
? ? ?*
? ? ?* @param key
? ? ?* @param dataMap
? ? ?*/
? ? public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
? ? {
? ? ? ? if (dataMap != null) {
? ? ? ? ? ? redisTemplate.opsForHash().putAll(key, dataMap);
? ? ? ? }
? ? }

? ? /**
? ? ?* 獲得緩存的Map
? ? ?*
? ? ?* @param key
? ? ?* @return
? ? ?*/
? ? public <T> Map<String, T> getCacheMap(final String key)
? ? {
? ? ? ? return redisTemplate.opsForHash().entries(key);
? ? }

? ? /**
? ? ?* 往Hash中存入數(shù)據(jù)
? ? ?*
? ? ?* @param key Redis鍵
? ? ?* @param hKey Hash鍵
? ? ?* @param value 值
? ? ?*/
? ? public <T> void setCacheMapValue(final String key, final String hKey, final T value)
? ? {
? ? ? ? redisTemplate.opsForHash().put(key, hKey, value);
? ? }

? ? /**
? ? ?* 獲取Hash中的數(shù)據(jù)
? ? ?*
? ? ?* @param key Redis鍵
? ? ?* @param hKey Hash鍵
? ? ?* @return Hash中的對(duì)象
? ? ?*/
? ? public <T> T getCacheMapValue(final String key, final String hKey)
? ? {
? ? ? ? HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
? ? ? ? return opsForHash.get(key, hKey);
? ? }

? ? /**
? ? ?* 獲取多個(gè)Hash中的數(shù)據(jù)
? ? ?*
? ? ?* @param key Redis鍵
? ? ?* @param hKeys Hash鍵集合
? ? ?* @return Hash對(duì)象集合
? ? ?*/
? ? public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
? ? {
? ? ? ? return redisTemplate.opsForHash().multiGet(key, hKeys);
? ? }

? ? /**
? ? ?* 獲得緩存的基本對(duì)象列表
? ? ?*
? ? ?* @param pattern 字符串前綴
? ? ?* @return 對(duì)象列表
? ? ?*/
? ? public Collection<String> keys(final String pattern)
? ? {
? ? ? ? return redisTemplate.keys(pattern);
? ? }

? ? /**
? ? ?* 判斷key是否還在
? ? ?* @param key
? ? ?* @return
? ? ?*/
? ? public boolean hasKey(final String key){
? ? ? ? return redisTemplate.hasKey(key);
? ? }
}

到此這篇關(guān)于springboot冪等切片的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)springboot冪等切片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java9新特性對(duì)HTTP2協(xié)議支持與非阻塞HTTP?API

    Java9新特性對(duì)HTTP2協(xié)議支持與非阻塞HTTP?API

    這篇文章主要為大家介紹了Java9新特性對(duì)HTTP2協(xié)議的支持與非阻塞HTTP?API,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • Spring Boot Shiro在Web應(yīng)用中的作用詳解

    Spring Boot Shiro在Web應(yīng)用中的作用詳解

    這篇文章主要為大家介紹了Spring Boot Shiro在Web應(yīng)用中的作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Java圖片與二進(jìn)制相互轉(zhuǎn)換實(shí)現(xiàn)示例講解

    Java圖片與二進(jìn)制相互轉(zhuǎn)換實(shí)現(xiàn)示例講解

    這篇文章主要介紹了Java圖片與二進(jìn)制相互轉(zhuǎn)換實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-03-03
  • java同步鎖的正確使用方法(必看篇)

    java同步鎖的正確使用方法(必看篇)

    下面小編就為大家?guī)硪黄猨ava同步鎖的正確使用方法(必看篇)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • 深入解析Java并發(fā)程序中線程的同步與線程鎖的使用

    深入解析Java并發(fā)程序中線程的同步與線程鎖的使用

    這篇文章主要介紹了深入解析Java并發(fā)編程中線程的同步與線程鎖的使用,synchronized和lock是Java中最常見的控制線程的方法,需要的朋友可以參考下
    2016-03-03
  • 部署Nacos的源碼環(huán)境搭建過程

    部署Nacos的源碼環(huán)境搭建過程

    這篇文章主要為大家介紹了部署Nacos的源碼環(huán)境搭建過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Java大數(shù)據(jù)開發(fā)Hadoop?MapReduce

    Java大數(shù)據(jù)開發(fā)Hadoop?MapReduce

    MapReduce的思想核心是“分而治之”,適用于大量復(fù)雜的任務(wù)處理場景(大規(guī)模數(shù)據(jù)處理場景)Map負(fù)責(zé)“分”,即把復(fù)雜的任務(wù)分解為若干個(gè)“簡單的任務(wù)”來并行處理??梢赃M(jìn)行拆分的前提是這些小任務(wù)可以并行計(jì)算,彼此間幾乎沒有依賴關(guān)系
    2023-03-03
  • Java線程的基本概念

    Java線程的基本概念

    本文主要介紹了Java線程的基本概念。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • SimpleDateFormat線程安全問題排查詳解

    SimpleDateFormat線程安全問題排查詳解

    這篇文章主要為大家介紹了SimpleDateFormat線程安全問題排查詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • idea使用Maven Helper插件去掉無用的poom 依賴信息(詳細(xì)步驟)

    idea使用Maven Helper插件去掉無用的poom 依賴信息(詳細(xì)步驟)

    這篇文章主要介紹了idea使用Maven Helper插件去掉無用的poom 依賴信息,本文分步驟給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04

最新評(píng)論