最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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("請勿重復(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot項(xiàng)目中新增脫敏功能的實(shí)例代碼

    SpringBoot項(xiàng)目中新增脫敏功能的實(shí)例代碼

    項(xiàng)目中,由于使用端有兩個(gè),對(duì)于兩個(gè)端的數(shù)據(jù)權(quán)限并不一樣。Web端可以查看所有數(shù)據(jù),小程序端只能查看脫敏后的數(shù)據(jù),這篇文章主要介紹了SpringBoot項(xiàng)目中新增脫敏功能,需要的朋友可以參考下
    2022-11-11
  • 如何使用mybatis-plus實(shí)現(xiàn)分頁查詢功能

    如何使用mybatis-plus實(shí)現(xiàn)分頁查詢功能

    最近在研究mybatis,然后就去找簡化mybatis開發(fā)的工具,發(fā)現(xiàn)就有通用Mapper和mybatis-plus兩個(gè)比較好的可是使用,可是經(jīng)過對(duì)比發(fā)現(xiàn)還是mybatis-plus比較好,下面這篇文章主要給大家介紹了關(guān)于如何使用mybatis-plus實(shí)現(xiàn)分頁查詢功能的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • springboot?vue接口測試定義編輯功能的實(shí)現(xiàn)

    springboot?vue接口測試定義編輯功能的實(shí)現(xiàn)

    這篇文章主要為大家介紹了springboot?vue接口測試定義編輯功能的實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Java中List轉(zhuǎn)Map的幾種具體實(shí)現(xiàn)方式和特點(diǎn)

    Java中List轉(zhuǎn)Map的幾種具體實(shí)現(xiàn)方式和特點(diǎn)

    這篇文章主要介紹了幾種常用的List轉(zhuǎn)Map的方式,包括使用for循環(huán)遍歷、Java8StreamAPI、ApacheCommonsCollections和GoogleGuava,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-01-01
  • Spring AOP實(shí)現(xiàn)權(quán)限檢查的功能

    Spring AOP實(shí)現(xiàn)權(quán)限檢查的功能

    這篇文章主要介紹了Spring AOP實(shí)現(xiàn)權(quán)限檢查的功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • SpringMVC?RESTFul實(shí)體類創(chuàng)建及環(huán)境搭建

    SpringMVC?RESTFul實(shí)體類創(chuàng)建及環(huán)境搭建

    這篇文章主要為大家介紹了SpringMVC?RESTFul實(shí)體類創(chuàng)建及環(huán)境搭建詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • SpringBoot?使用log4j2的配置過程

    SpringBoot?使用log4j2的配置過程

    這篇文章主要介紹了SpringBoot?使用log4j2的配置,springboot默認(rèn)是用logback的日志框架的,所以要在pom中配置排除logback。這里需要注意的是,其實(shí)不止一處使用了logback,所以要在starter中統(tǒng)一排除,然后引入log4j2,需要的朋友可以參考下
    2022-09-09
  • Java文件大小轉(zhuǎn)換的兩種方式小結(jié)

    Java文件大小轉(zhuǎn)換的兩種方式小結(jié)

    在程序開發(fā)的過程中,文件的大小在視圖呈現(xiàn)和數(shù)據(jù)庫存儲(chǔ)的過程不一致怎么轉(zhuǎn)換呢,本文主要介紹了Java文件大小轉(zhuǎn)換的兩種方式小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • Character.UnicodeBlock中cjk的說明詳解

    Character.UnicodeBlock中cjk的說明詳解

    這篇文章主要為大家詳細(xì)介紹了Character.UnicodeBlock中cjk的說明,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • java后臺(tái)利用Apache poi 生成excel文檔提供前臺(tái)下載示例

    java后臺(tái)利用Apache poi 生成excel文檔提供前臺(tái)下載示例

    本篇文章主要介紹了java后臺(tái)利用Apache poi 生成excel文檔提供前臺(tái)下載示例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-05-05

最新評(píng)論

双峰县| 南投县| 乌拉特前旗| 甘孜县| 简阳市| 莆田市| 邢台县| 洞头县| 敦煌市| 台中县| 崇信县| 万源市| 桃园市| 梓潼县| 阳西县| 武隆县| 礼泉县| 溆浦县| 桦南县| 剑阁县| 柘城县| 邮箱| 英吉沙县| 隆尧县| 洛阳市| 含山县| 郑州市| 环江| 阿鲁科尔沁旗| 五原县| 黑河市| 泰州市| 湖北省| 罗山县| 天峨县| 康乐县| 易门县| 上林县| 胶州市| 克东县| 正安县|