一個(gè)注解搞定 SpringBoot 接口防刷,還有誰不會(huì)?
說明:使用了注解的方式進(jìn)行對(duì)接口防刷的功能,非常高大上,本文章僅供參考。
技術(shù)要點(diǎn):springboot的基本知識(shí),redis基本操作。
首先是寫一個(gè)注解類:
import?java.lang.annotation.Retention;
import?java.lang.annotation.Target;
?
import?static?java.lang.annotation.ElementType.METHOD;
import?static?java.lang.annotation.RetentionPolicy.RUNTIME;
?
/**
?*?@author?yhq
?*?@date?2018/9/10?15:52
?*/
?
@Retention(RUNTIME)
@Target(METHOD)
public?@interface?AccessLimit?{
?
????int?seconds();
????int?maxCount();
????boolean?needLogin()default?true;
}接著就是在Interceptor攔截器中實(shí)現(xiàn):
import?com.alibaba.fastjson.JSON;
import?com.example.demo.action.AccessLimit;
import?com.example.demo.redis.RedisService;
import?com.example.demo.result.CodeMsg;
import?com.example.demo.result.Result;
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.stereotype.Component;
import?org.springframework.web.method.HandlerMethod;
import?org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
?
import?javax.servlet.http.HttpServletRequest;
import?javax.servlet.http.HttpServletResponse;
import?java.io.OutputStream;
?
/**
?*?@author?yhq
?*?@date?2018/9/10?16:05
?*/
?
?
@Component
public?class?FangshuaInterceptor?extends?HandlerInterceptorAdapter?{
?
????@Autowired
????private?RedisService?redisService;
?
????@Override
????public?boolean?preHandle(HttpServletRequest?request,?HttpServletResponse?response,?Object?handler)?throws?Exception?{
?
????????//判斷請(qǐng)求是否屬于方法的請(qǐng)求
????????if(handler?instanceof?HandlerMethod){
?
????????????HandlerMethod?hm?=?(HandlerMethod)?handler;
?
????????????//獲取方法中的注解,看是否有該注解
????????????AccessLimit?accessLimit?=?hm.getMethodAnnotation(AccessLimit.class);
????????????if(accessLimit?==?null){
????????????????return?true;
????????????}
????????????int?seconds?=?accessLimit.seconds();
????????????int?maxCount?=?accessLimit.maxCount();
????????????boolean?login?=?accessLimit.needLogin();
????????????String?key?=?request.getRequestURI();
????????????//如果需要登錄
????????????if(login){
????????????????//獲取登錄的session進(jìn)行判斷
????????????????//.....
????????????????key+=""+"1";??//這里假設(shè)用戶是1,項(xiàng)目中是動(dòng)態(tài)獲取的userId
????????????}
?
????????????//從redis中獲取用戶訪問的次數(shù)
????????????AccessKey?ak?=?AccessKey.withExpire(seconds);
????????????Integer?count?=?redisService.get(ak,key,Integer.class);
????????????if(count?==?null){
????????????????//第一次訪問
????????????????redisService.set(ak,key,1);
????????????}else?if(count?????????????????//加1
????????????????redisService.incr(ak,key);
????????????}else{
????????????????//超出訪問次數(shù)
????????????????render(response,CodeMsg.ACCESS_LIMIT_REACHED);?//這里的CodeMsg是一個(gè)返回參數(shù)
????????????????return?false;
????????????}
????????}
?
????????return?true;
?
????}
????private?void?render(HttpServletResponse?response,?CodeMsg?cm)throws?Exception?{
????????response.setContentType("application/json;charset=UTF-8");
????????OutputStream?out?=?response.getOutputStream();
????????String?str??=?JSON.toJSONString(Result.error(cm));
????????out.write(str.getBytes("UTF-8"));
????????out.flush();
????????out.close();
????}
}再把Interceptor注冊(cè)到springboot中
import?com.example.demo.ExceptionHander.FangshuaInterceptor;
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.context.annotation.Configuration;
import?org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import?org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
?
/**
?*?@author?yhq
?*?@date?2018/9/10?15:58
?*/
@Configuration
public?class?WebConfig?extends?WebMvcConfigurerAdapter?{
?
????@Autowired
????private?FangshuaInterceptor?interceptor;
?
?
????@Override
????public?void?addInterceptors(InterceptorRegistry?registry)?{
????????registry.addInterceptor(interceptor);
????}
}
接著在Controller中加入注解
import?com.example.demo.result.Result;
import?org.springframework.stereotype.Controller;
import?org.springframework.web.bind.annotation.RequestMapping;
import?org.springframework.web.bind.annotation.ResponseBody;
?
/**
?*?@author?yhq
?*?@date?2018/9/10?15:49
?*/
?
@Controller
public?class?FangshuaController?{
?
????@AccessLimit(seconds=5,?maxCount=5,?needLogin=true)
????@RequestMapping("/fangshua")
????@ResponseBody
????public?Result?fangshua() {
?
?
????????return?Result.success("請(qǐng)求成功");
?
????}
????
}????本文有參考其他視頻的教學(xué),希望可以幫助更多熱愛it行業(yè)的人。
作者:CS打贏你
本文鏈接:https://blog.csdn.net/weixin_42533856/article/details/82593123
評(píng)論
圖片
表情
