一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

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

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

服務器之家 - 編程語言 - Java教程 - SpringBoot中自定義注解實現控制器訪問次數限制實例

SpringBoot中自定義注解實現控制器訪問次數限制實例

2020-09-09 13:41漫步于成神之路男人 Java教程

本篇文章主要介紹了SpringBoot中自定義注解實現控制器訪問次數限制實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。

今天給大家介紹一下SpringBoot中如何自定義注解實現控制器訪問次數限制。

在Web中最經常發生的就是利用惡性URL訪問刷爆服務器之類的攻擊,今天我就給大家介紹一下如何利用自定義注解實現這類攻擊的防御操作。

其實這類問題一般的解決思路就是:在控制器中加入自定義注解實現訪問次數限制的功能。

具體的實現過程看下面的例子:

步驟一:先定義一個注解類,下面看代碼事例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package example.controller.limit;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
//最高優先級
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface RequestLimit {
  /**
   *
   * 允許訪問的次數,默認值MAX_VALUE
   */
  int count() default Integer.MAX_VALUE;
 
  /**
   *
   * 時間段,單位為毫秒,默認值一分鐘
   */
  long time() default 60000;
}

步驟二:定義一個異常類,用來處理URL攻擊時產生的異常問題,下面看代碼事例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
package example.controller.exception;
public class RequestLimitException extends Exception {
  private static final long serialVersionUID = 1364225358754654702L;
 
  public RequestLimitException() {
    super("HTTP請求超出設定的限制");
  }
 
  public RequestLimitException(String message) {
    super(message);
  }
 
}

步驟三:定義一個注解的具體實現類,下面看代碼事例:

?
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
package example.controller.limit;
import example.controller.exception.RequestLimitException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
 
@Aspect
@Component
public class RequestLimitContract {
  private static final Logger logger = LoggerFactory.getLogger("RequestLimitLogger");
  private Map<String, Integer> redisTemplate=new HashMap<String,Integer>();
  @Before("within(@org.springframework.stereotype.Controller *) && @annotation(limit)")
  public void requestLimit(final JoinPoint joinPoint, RequestLimit limit) throws RequestLimitException {
    try {
      Object[] args = joinPoint.getArgs();
      HttpServletRequest request = null;
      for (int i = 0; i < args.length; i++) {
        if (args[i] instanceof HttpServletRequest) {
          request = (HttpServletRequest) args[i];
          break;
        }
      }
      if (request == null) {
        throw new RequestLimitException("方法中缺失HttpServletRequest參數");
      }
      String ip = request.getLocalAddr();
      String url = request.getRequestURL().toString();
      String key = "req_limit_".concat(url).concat(ip);
      if(redisTemplate.get(key)==null || redisTemplate.get(key)==0){
        redisTemplate.put(key,1);
      }else{
        redisTemplate.put(key,redisTemplate.get(key)+1);
      }
      int count = redisTemplate.get(key);
      if (count > 0) {
        Timer timer= new Timer();
        TimerTask task = new TimerTask(){  //創建一個新的計時器任務。
          @Override
          public void run() {
            redisTemplate.remove(key);
          }
        };
        timer.schedule(task, limit.time());
        //安排在指定延遲后執行指定的任務。task : 所要安排的任務。10000 : 執行任務前的延遲時間,單位是毫秒。
      }
      if (count > limit.count()) {
        //logger.info("用戶IP[" + ip + "]訪問地址[" + url + "]超過了限定的次數[" + limit.count() + "]");
        throw new RequestLimitException();
      }
    } catch (RequestLimitException e) {
      throw e;
    } catch (Exception e) {
      logger.error("發生異常: ", e);
    }
  }
}

步驟四:實現一個控制類,并添加使用注解功能。下面看代碼事例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package example.controller;
import example.controller.limit.RequestLimit;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
@Controller
public class URLController {
  @RequestLimit(count=10,time=5000)
  @RequestMapping("/urltest")
  @ResponseBody
  public String test(HttpServletRequest request, ModelMap modelMap) {
    return "aaa";
  }
}

 其中count指的是規定時間內的訪問次數,time指的就是規定時間,單位為毫秒。

這樣就實現了在控制器這個層次上面的url攔截了。不過這里有個問題,就是如果想在每一個URL頁面上面都進行這樣的攔截,這種方法明顯是不夠的。因為我們不可能在每個控制器上面都加上url攔截的注解,所以這種方法只適合在某些特定的URL攔截上面使用它們。

那如何實現過濾器級別上面的URL訪問攔截呢?這里先給大家賣一個關子,我將會在下一節中給大家介紹如何利用過濾器實現URl訪問攔截,并且利用JPA實現ip黑名單的功能,加入IP黑名單后就不可以進行任何URL的訪問了。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://blog.csdn.net/linzhiqiang0316/article/details/52671293

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人不卡在线 | 青青草原国产一区二区 | 亚洲精品午夜在线观看 | 欧美香蕉 | 久久这里只有精品视频e | 四虎院影永久在线观看 | 午夜国产在线 | 免费人成网址在线观看国内 | 亚洲天堂在线视频播放 | 农村老妇1乱69系列小说 | 欧美女孩13一14v | 国产精品永久免费自在线观看 | 国产成人一区二区三区影院免费 | julia ann一hd| 欧美人与禽交片在线播放 | 午夜影院0606免费 | 四虎2020紧急免费入口 | 范冰冰上面好大下面好紧 | 男人久久天堂 | 奶茶视频官网免费 | 99精品偷自拍 | 欧美日本一道高清免费3区 欧美人做人爱a全程免费 | 4hc44四虎www在线影院男同 | 3344在线看片 | 亚洲热在线观看 | 男女肉粗暴进来下面好紧 | 欧美一区二区三区免费看 | 天天干天天色综合 | 亚洲精品国产一区二区三区在 | 精品在线视频一区 | 国产视频一区在线观看 | 久久国产精品二区99 | 超级碰碰青草免费视频92 | 四虎影视在线观看永久地址 | 欧美a一片xxxx片与善交 | 日韩欧美中文字幕一区二区三区 | 天天综合五月天 | 小小水蜜桃免费影院 | 日韩丝袜在线观看 | 国产欧美一区二区精品性色 | 草莓污污 |