国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java結合redis實現接口防重復提交

Java結合redis實現接口防重復提交

2022-01-11 00:50帆非凡 Java教程

本文主要介紹了Java結合redis實現接口防重復提交,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

redis 接口防重

技術點:redis/aop

說明:

簡易版本實現防止重復提交,適用范圍為所有接口適用,采用注解方式,在需要防重的接口上使用注解,可以設置防重時效。

場景:

在系統中,經常會有一些接口會莫名其妙的被調用兩次,可能在冪等接口中不會存在太大的問題,但是非冪等接口的處理就會導致出現臟數據,甚至影響系統的正確性。

選型參考:

在常見的防重處理分為多種,粗分為前端處理,后端處理

前端處理分為:

  • 在按鈕觸發后便將按鈕置灰,設置為不可用,在接口調用成功后回調處理,將按鈕恢復
  • 發送請求時,設置一個狀態,在接口請求時去獲取狀態,查看在保護期是否已經有調用,思路與第一條類似

后端處理分為:

  • 版本號,在數據表中增加version字段,在我們需要進行防重的接口請求到達后端后,sql處理時增加版本號條件(切記:每次在修改操作后需要對版本號進行加1哦),如果不一致則不進行處理。這也是樂觀鎖實現的一種思路。
  • redis,即本文所述方式

選型原因

  • 在系統安全中,防重復提交也是比較重要的一個指標,也就是接口冪等性。所以我們在日常的系統開發中,一般使用的是簡化版的放重復。也就是僅僅通過前端來進行防重控制,但是這樣也是具有風險性的。如果在涉及比較重要的數據的時候,可能往往會有熱心同行來幫我們找bug,對于他們可以直接通過抓報文的方式拿到我們的交互信息,以此來進行各種騷操作(羊毛黨做派,當然了,如果要避免接口攻擊,我們還要設置ip請求限制,小黑屋,防DDOS等各種防御工作,此處只講防重咯)。所以我們在重要數據處理時在后端也是同樣需要進行防重處理的。
  • 防重提交的方式非常非常多,如上提出了四種方式,也只是冰山一角了。針對于后端側防重,如上簡述了兩種方式。個人覺得在不同的時機可以進行不同的選擇。如果我們在項目初期,個人覺得使用版本號處理更為合適一點,這樣會降低對第三方工具的依賴,因為我們在每加入一個新東西的時候都是會增加系統的復雜性的。我們在考慮性能,安全,可靠的時候就會多出一個事項,有點給自己找事做的樣子。但是如果我們的系統已經較為平穩了,那么此時對數據庫進行增加字段雖然也不會太難,但是會改動一些代碼。驚喜總是從這些地方來的。使用redis我覺得就要合適一些了,我們只需要面向切面進行編程,一處編寫,處處可用。從代碼和擴展來講redis就更為合適了。

以上內容都是瞎BB的,其實我也是個菜鳥,歡迎各位大佬提建議或者意見,大家共同進步,共同完善,讓java圈充滿激情四射的愛。

代碼樣例

?
1
2
3
4
5
6
@PostMapping("/user/update")
@ApiOperation(value = "修改用戶信息", notes = "修改用戶信息", tags = "user module")
@AvoidReSubmit(expireTime = 1000 * 3)
public void update(@RequestBody User user){
 userMapper.updateById(user);
}

具體代碼實現

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 定義自定義注解,設置注解參數默認值
package top.withu.gaof.freehope.annotate;
 
import java.lang.annotation.*;
 
 
/**
 * @author Gaofan
 * @date 2019年10月12日 下午2:54:45
 * @describe 防止重復提交
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AvoidReSubmit {
 
    /**
     * 失效時間,即可以第二次提交間隔時長
     * @return
     */
    long expireTime() default 30 * 1000L;
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// 定義切面進行處理
package top.withu.gaof.freehope.aspect;
 
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import top.withu.gaof.freehope.annotate.AvoidReSubmit;
 
import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;
 
/**
 * @Description: TODO
 * @Author: gaofan
 * @Date: 2019/10/12 16:10
 * @Copyright: 2019 www.blog.freehope.top Inc. All rights reserved.
 **/
@Aspect
@Component
public class AvoidResumitAspect {
 
    @Resource
    private RedisTemplate redisTemplate;
 
    /**
     * 定義匹配規則,以便于后續攔截直接攔截submit方法,不用重復表達式
     */
    @Pointcut(value = "@annotation(top.withu.gaof.freehope.annotate.AvoidReSubmit)")
    public void submit() {
    }
 
    @Before("submit()&&@annotation(avoidReSubmit)")
    public void doBefore(JoinPoint joinPoint, AvoidReSubmit avoidReSubmit) {
 
        // 拼裝參數
        StringBuffer sb = new StringBuffer();
        for(Object object : joinPoint.getArgs()){
            sb.append(object);
        }
 
        String key = md5(sb.toString());
        long expireTime = avoidReSubmit.expireTime();
        ValueOperations valueOperations = redisTemplate.opsForValue();
        Object object = valueOperations.get(key);
        if(null != object){
            throw new RuntimeException("您已經提交了請求,請不要重復提交哦!");
        }
        valueOperations.set(key, 1, expireTime, TimeUnit.MILLISECONDS);
    }
 
    @Around("submit()&&@annotation(avoidReSubmit)")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint, AvoidReSubmit avoidReSubmit) throws Throwable {
        System.out.println("環繞通知:");
        Object result = null;
        result = proceedingJoinPoint.proceed();
        return result;
    }
 
    @After("submit()")
    public void doAfter() {
        System.out.println("******攔截后的邏輯******");
    }
 
    private String md5(String str){
        if (str == null || str.length() == 0) {
            throw new IllegalArgumentException("String to encript cannot be null or zero length");
        }
        StringBuffer hexString = new StringBuffer();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte[] hash = md.digest();
            for (int i = 0; i < hash.length; i++) {
                if ((0xff & hash[i]) < 0x10) {
                    hexString.append("0" + Integer.toHexString((0xFF & hash[i])));
                } else {
                    hexString.append(Integer.toHexString(0xFF & hash[i]));
                }
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return hexString.toString();
    }
}

思路:

簡單的通過redis實現,估計版本在網上非常多了。這里的一個思路還是mark一下,現在我這代碼只有我和上帝知道什么意思,我怕一個月以后就只有上帝知道了。

  • 自定義注解,注解中申明有效時間
  • 使用aop切面攔截自定義注解,獲取注解中有效時間參數,此處默認設置保護期為30 * 1000L,單位毫秒
  • 在切面中獲取接口請求的參數,將參數拼接成string,然后進行md5,這樣操作是因為降低key長度,避免看起來過于惡心。但是這里有一個情況沒有進行測試,那就是key碰撞的問題。在大量數據操作下是否會產生相同key值。
  • 使用md5加密后的key值到redis中查詢,如果存在記錄則表明已經有接口訪問且處于保護期,不可繼續提交。此處使用異常處理。如果不存在記錄,則表明此接口在保護期內沒有訪問過,則不操作。此處的場景在使用時可以根據自己需求而定。
  • 此處在環繞通知和after通知均沒有操作,因為我們只是對于放重復提交處理,業務場景中不存在后處理的情況,故而沒有具體實現。

到此這篇關于Java結合redis實現接口防重復提交的文章就介紹到這了,更多相關redis 接口防重復提交內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家! 

原文鏈接:https://blog.csdn.net/sky_demo/article/details/102525226

延伸 · 閱讀

精彩推薦
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产高清免费视频 | 亚洲国产精品欧美一二99 | 毛片免费观看视频 | 欧美成人二区 | 欧美一级一 | 国产一区二区在线播放 | 国产不卡一区 | 亚洲精品久久久一区二区三区 | 日韩中文一区二区三区 | 99久久婷婷国产综合精品电影 | 久久亚洲精品视频 | 看a网站| 亚洲最新无码中文字幕久久 | 成人免费黄色毛片 | 一区二区不卡视频 | 久久精品国产一区二区三区不卡 | 久久久久av| 成人精品鲁一区一区二区 | 综合伊人 | 欧美一区二区三区在线 | 欧美一区二区三区免费观看视频 | 欧美日韩亚洲一区二区 | 亚洲欧美一区二区三区久久 | 久草免费在线 | 日韩在线一区二区三区免费视频 | 亚洲视频免费观看 | 粉嫩欧美一区二区三区高清影视 | 国产精品美女久久久久av麻豆 | 日韩在线看片 | 久久久久999| 久久久久久久国产 | 精品国产乱码一区二区三区 | 国产中文字幕亚洲 | 日本精品一区二区三区在线观看视频 | 高清hd写真福利在线播放 | 国产美女视频自拍 | 欧美中文字幕一区二区 | av影音 | 国产精品久久久久久久午夜片 | 天堂俺去俺来也www久久婷婷 | 国产一区二区三区免费 |