对码当歌,猿生几何?

Springboot项目的接口防刷

说明:使用了注解的方式进行对接口防刷的功能,非常高大上,本文章仅供参考 一,技术要点:springboot的基本知识,redis基本操作,

首先是写一个注解类:

  1. import java.lang.annotation.Retention;

  2. import java.lang.annotation.Target;


  3. import static java.lang.annotation.ElementType.METHOD;

  4. import static java.lang.annotation.RetentionPolicy.RUNTIME;



  5. @Retention(RUNTIME)

  6. @Target(METHOD)

  7. public @interface AccessLimit {


  8.    int seconds();

  9.    int maxCount();

  10.    boolean needLogin()default true;

  11. }

拦截器中实现:


  1. import com.alibaba.fastjson.JSON;

  2. import com.example.demo.action.AccessLimit;

  3. import com.example.demo.redis.RedisService;

  4. import com.example.demo.result.CodeMsg;

  5. import com.example.demo.result.Result;

  6. import org.springframework.beans.factory.annotation.Autowired;

  7. import org.springframework.stereotype.Component;

  8. import org.springframework.web.method.HandlerMethod;

  9. import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;


  10. import javax.servlet.http.HttpServletRequest;

  11. import javax.servlet.http.HttpServletResponse;

  12. import java.io.OutputStream;




  13. @Component

  14. public class FangshuaInterceptor extends HandlerInterceptorAdapter {


  15.    @Autowired

  16.    private RedisService redisService;


  17.    @Override

  18.    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {


  19.        //判断请求是否属于方法的请求

  20.        if(handler instanceof HandlerMethod){


  21.            HandlerMethod hm = (HandlerMethod) handler;


  22.            //获取方法中的注解,看是否有该注解

  23.            AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);

  24.            if(accessLimit == null){

  25.                return true;

  26.            }

  27.            int seconds = accessLimit.seconds();

  28.            int maxCount = accessLimit.maxCount();

  29.            boolean login = accessLimit.needLogin();

  30.            String key = request.getRequestURI();

  31.            //如果需要登录

  32.            if(login){

  33.                //获取登录的session进行判断

  34.                //.....

  35.                key+=""+"1";  //这里假设用户是1,项目中是动态获取的userId

  36.            }


  37.            //从redis中获取用户访问的次数

  38.            AccessKey ak = AccessKey.withExpire(seconds);

  39.            Integer count = redisService.get(ak,key,Integer.class);

  40.            if(count == null){

  41.                //第一次访问

  42.                redisService.set(ak,key,1);

  43.            }else if(count < maxCount){

  44.                //加1

  45.                redisService.incr(ak,key);

  46.            }else{

  47.                //超出访问次数

  48.                render(response,CodeMsg.ACCESS_LIMIT_REACHED); //这里的CodeMsg是一个返回参数

  49.                return false;

  50.            }

  51.        }


  52.        return true;


  53.    }

  54.    private void render(HttpServletResponse response, CodeMsg cm)throws Exception {

  55.        response.setContentType("application/json;charset=UTF-8");

  56.        OutputStream out = response.getOutputStream();

  57.        String str  = JSON.toJSONString(Result.error(cm));

  58.        out.write(str.getBytes("UTF-8"));

  59.        out.flush();

  60.        out.close();

  61.    }

  62. }

注册到springboot中

  1. import com.example.demo.ExceptionHander.FangshuaInterceptor;

  2. import org.springframework.beans.factory.annotation.Autowired;

  3. import org.springframework.context.annotation.Configuration;

  4. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

  5. import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;


  6. @Configuration

  7. public class WebConfig extends WebMvcConfigurerAdapter {


  8.    @Autowired

  9.    private FangshuaInterceptor interceptor;



  10.    @Override

  11.    public void addInterceptors(InterceptorRegistry registry) {

  12.        registry.addInterceptor(interceptor);

  13.    }

  14. }

在Controller中加入注解

最后,给大家推荐一个Java进阶交流群851531810,不管你在地球哪个方位,不管你参加工作几年都欢迎你的入驻!(群内会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)

  1. import com.example.demo.result.Result;

  2. import org.springframework.stereotype.Controller;

  3. import org.springframework.web.bind.annotation.RequestMapping;

  4. import org.springframework.web.bind.annotation.ResponseBody;



  5. @Controller

  6. public class FangshuaController {


  7.    @AccessLimit(seconds=5, maxCount=5, needLogin=true)

  8.    @RequestMapping("/fangshua")

  9.    @ResponseBody

  10.    public Result<String&gt; fangshua(){



  11.        return Result.success("请求成功");

  12. }