SpringBoot3利用AOP實(shí)現(xiàn)IP黑名單功能
本文主要介紹如何使用AOP實(shí)現(xiàn)IP黑名單功能
主要涉及三個(gè)類
- 注解類
- 切面實(shí)現(xiàn)類
- Controller類
注解類
在注解中包含了幾個(gè)檢測參數(shù)
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface IPBlackList { int maxRequests() default 10; // 最大請(qǐng)求次數(shù) long timeWindow() default 60000L; // 計(jì)數(shù)時(shí)間窗口,單位:毫秒 long blockTime() default 60000L; // 拉黑時(shí)間,單位:毫秒 }
切面實(shí)現(xiàn)
在doBefore方法中我調(diào)了自己的工具類不過就是一個(gè)獲取請(qǐng)求ip的方法,還有我過濾了內(nèi)網(wǎng)ip,如果不需要可以去掉。
@Aspect @Component public class IPBlackListAspect { private final Map<String, List<Long>> requestTimes = new ConcurrentHashMap<>(); private final Map<String, Long> blackList = new ConcurrentHashMap<>(); @Before(value = "@annotation(ipBlackList)") public void doBefore(IPBlackList ipBlackList) { String clientIP = ServletUtils.getClientIP(); if (StringUtils.isBlank(clientIP)) { return; } // 內(nèi)網(wǎng)不查詢 clientIP = StringUtils.contains(clientIP, "0:0:0:0:0:0:0:1") ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(clientIP); if (NetUtil.isInnerIP(clientIP)) { return; } int maxRequests = ipBlackList.maxRequests(); long timeWindow = ipBlackList.timeWindow(); long blockTime = ipBlackList.blockTime(); long currentTime = System.currentTimeMillis(); // 檢查 IP 是否在黑名單中 if (blackList.containsKey(clientIP)) { long blacklistedAt = blackList.get(clientIP); if (currentTime - blacklistedAt < blockTime) { throw new RuntimeException("IP 已被拉黑,請(qǐng)稍后再試"); } else { blackList.remove(clientIP); // 移除過期的黑名單記錄 blackList.remove(clientIP); // 重置計(jì)時(shí) } } // 獲取該 IP 的訪問記錄并清除超過時(shí)間窗口的記錄 List<Long> times = requestTimes.getOrDefault(clientIP, new CopyOnWriteArrayList<>()); times.removeIf(time -> currentTime - time > timeWindow); times.add(currentTime); // 記錄當(dāng)前訪問時(shí)間 requestTimes.put(clientIP, times); // 檢查在時(shí)間窗口內(nèi)的請(qǐng)求次數(shù) if (times.size() > maxRequests) { blackList.put(clientIP, currentTime); // 拉黑 IP throw new RuntimeException("請(qǐng)求次數(shù)過多,IP 已被拉黑"); } } }
Controller
只要在Http請(qǐng)求方法上加上上面定義的注解就可以
@RestController() @RequestMapping("/auth/auth") public class YunfuAuthController { @Resource private IYunfuAuthService yunfuAuthService; @PostMapping @SaIgnore @IPBlackList public R<YunfuAuthVo> auth(YunfuAuthBo bo){ return R.ok(yunfuAuthService.auth(bo)); } }
后言
到此這篇關(guān)于SpringBoot3利用AOP實(shí)現(xiàn)IP黑名單功能的文章就介紹到這了,更多相關(guān)SpringBoot3 IP黑名單內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java注解結(jié)合aspectj AOP進(jìn)行日志打印的操作
這篇文章主要介紹了java注解結(jié)合aspectj AOP進(jìn)行日志打印的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02java基于servlet實(shí)現(xiàn)文件上傳功能解析
這篇文章主要為大家詳細(xì)介紹了java基于servlet實(shí)現(xiàn)上傳功能,后臺(tái)使用java實(shí)現(xiàn),前端主要是js的ajax實(shí)現(xiàn),感興趣的小伙伴們可以參考一下2016-05-05IDEA連接達(dá)夢(mèng)數(shù)據(jù)庫的詳細(xì)配置指南
達(dá)夢(mèng)數(shù)據(jù)庫(DM Database)作為國產(chǎn)關(guān)系型數(shù)據(jù)庫的代表,廣泛應(yīng)用于企業(yè)級(jí)系統(tǒng)開發(fā),本文將詳細(xì)介紹如何在IntelliJ IDEA中配置并連接達(dá)夢(mèng)數(shù)據(jù)庫,助力開發(fā)者高效完成數(shù)據(jù)庫開發(fā)工作,需要的朋友可以參考下2025-03-03SpringBoot 請(qǐng)求參數(shù)忽略大小寫的實(shí)例
這篇文章主要介紹了SpringBoot 請(qǐng)求參數(shù)忽略大小寫的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01springboot2如何集成ElasticSearch6.4.3
這篇文章主要介紹了springboot2如何集成ElasticSearch6.4.3問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07SpringCloud使用Feign實(shí)現(xiàn)遠(yuǎn)程調(diào)用流程詳細(xì)介紹
OpenFeign源于Netflix的Feign,是http通信的客戶端。屏蔽了網(wǎng)絡(luò)通信的細(xì)節(jié),直接面向接口的方式開發(fā),讓開發(fā)者感知不到網(wǎng)絡(luò)通信細(xì)節(jié)。所有遠(yuǎn)程調(diào)用,都像調(diào)用本地方法一樣完成2023-02-02Java的作業(yè)調(diào)度類庫Quartz基本使用指南
這篇文章主要介紹了Java的作業(yè)調(diào)度類庫Quartz基本使用指南,Quartz能夠讓類按照指定的計(jì)劃順序執(zhí)行,需要的朋友可以參考下2016-03-03java 畫pdf用itext調(diào)整表格寬度、自定義各個(gè)列寬的方法
這篇文章主要介紹了java 畫pdf用itext調(diào)整表格寬度、自定義各個(gè)列寬的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01