Springboot項目的接口防刷(實例)

  • 2019 年 12 月 6 日
  • 筆記

來源:https://urlify.cn/ERf6Rr

說明:使用了註解的方式進行對接口防刷的功能,非常高大上,本文章僅供參考。

技術要點:springboot的基本知識,redis基本操作,

首先是寫一個註解類:

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攔截器中實現:

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 {            //判斷請求是否屬於方法的請求          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進行判斷                  //.....                  key+=""+"1";  //這裡假設用戶是1,項目中是動態獲取的userId              }                //從redis中獲取用戶訪問的次數              AccessKey ak = AccessKey.withExpire(seconds);              Integer count = redisService.get(ak,key,Integer.class);              if(count == null){                  //第一次訪問                  redisService.set(ak,key,1);              }else if(count < maxCount){                  //加1                  redisService.incr(ak,key);              }else{                  //超出訪問次數                  render(response,CodeMsg.ACCESS_LIMIT_REACHED); //這裡的CodeMsg是一個返回參數                  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註冊到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<String> fangshua(){              return Result.success("請求成功");        }  

本文有參考其他視頻的教學,希望可以幫助更多熱愛it行業的人。