乐趣区

关于java:牛X一个注解搞定接口防刷

阐明:应用了注解的形式进行对接口防刷的性能,十分高大上,本文章仅供参考。

技术要点: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 行业的人,

作者:CS 打赢你 \
本文链接:https://blog.csdn.net/weixin_…\
版权申明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协定,转载请附上原文出处链接和本申明。

近期热文举荐:

1.Java 15 正式公布,14 个新个性,刷新你的认知!!

2. 终于靠开源我的项目弄到 IntelliJ IDEA 激活码了,真香!

3. 我用 Java 8 写了一段逻辑,共事直呼看不懂,你试试看。。

4. 吊打 Tomcat,Undertow 性能很炸!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

退出移动版