首先是寫一個註解類:
1 @Retention(RUNTIME) 2 @Target(METHOD) 3 public @interface AccessLimit { 4 5 int seconds(); 6 int maxCount(); 7 boolean needLogin()default true; 8 }
接着就是在Interceptor攔截器中實現:
1 2 @Component 3 public class FangshuaInterceptor extends HandlerInterceptorAdapter { 4 5 @Autowired 6 private RedisService redisService; 7 8 @Override 9 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 10 11 //判斷請求是否屬於方法的請求 12 if(handler instanceof HandlerMethod){ 13 14 HandlerMethod hm = (HandlerMethod) handler; 15 16 //獲取方法中的註解,看是否有該註解 17 AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class); 18 if(accessLimit == null){ 19 return true; 20 } 21 int seconds = accessLimit.seconds(); 22 int maxCount = accessLimit.maxCount(); 23 boolean login = accessLimit.needLogin(); 24 String key = request.getRequestURI(); 25 //如果需要登錄 26 if(login){ 27 //獲取登錄的session進行判斷 28 //..... 29 key+=""+"1"; //這裏假設用戶是1,項目中是動態獲取的userId 30 } 31 32 //從redis中獲取用戶訪問的次數 33 AccessKey ak = AccessKey.withExpire(seconds); 34 Integer count = redisService.get(ak,key,Integer.class); 35 if(count == null){ 36 //第一次訪問 37 redisService.set(ak,key,1); 38 }else if(count < maxCount){ 39 //加1 40 redisService.incr(ak,key); 41 }else{ 42 //超出訪問次數 43 render(response,CodeMsg.ACCESS_LIMIT_REACHED); //這裏的CodeMsg是一個返回參數 44 return false; 45 } 46 } 47 48 return true; 49 50 } 51 private void render(HttpServletResponse response, CodeMsg cm)throws Exception { 52 response.setContentType("application/json;charset=UTF-8"); 53 OutputStream out = response.getOutputStream(); 54 String str = JSON.toJSONString(Result.error(cm)); 55 out.write(str.getBytes("UTF-8")); 56 out.flush(); 57 out.close(); 58 } 59 }
再把Interceptor註冊到springboot中
1 @Configuration 2 public class WebConfig extends WebMvcConfigurerAdapter { 3 4 @Autowired 5 private FangshuaInterceptor interceptor; 6 7 8 @Override 9 public void addInterceptors(InterceptorRegistry registry) { 10 registry.addInterceptor(interceptor); 11 } 12 }
接着在Controller中加入註解
1 @Controller 2 public class FangshuaController { 3 4 @AccessLimit(seconds=5, maxCount=5, needLogin=true) 5 @RequestMapping("/fangshua") 6 @ResponseBody 7 public Result<String> fangshua(){ 8 9 10 return Result.success("請求成功"); 11 12 }