Spring Boot 項目的 API 接口防刷


  • 首先是寫一個注解類

  • 攔截器中實現

  • 注冊到springboot中

  • 在Controller中加入注解

  • 說明:使用了注解的方式進行對接口防刷的功能,非常高大上,本文章僅供參考 一,技術要點: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;
    }

    攔截器

    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();
        }
    }

    注冊到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("請求成功");
    
        }

    相關參考:https://www.jianshu.com/p/364a6f466a2a

  •  

     

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM