1.对请求的接口做了一个限流的控制,
2.利用到:AOP,redis,定时器;
3.在请求的congtroller层上加相应的注解就可以;
具体的Demo工程如下
package ; import ; import .slf4j.Slf4j; import ; import ; import ; import ; import ; import ; import ; import ; ///befroe_You/article/details/83748927 @Aspect @Component @Slf4j public class RequestLimitContract { private Map<String, Integer> redisTemplate = (); @Before("within(@ *)&& @annotation(limit)") public void requestLimit(final JoinPoint joinPoint, RequestLimit limit) throws RequestLimitException { try { Object[] args = (); HttpServletRequest request = null; for (int i = 0; i < ; i++) { if (args[i] instanceof HttpServletRequest) { request = (HttpServletRequest) args[i]; break; } } /** * 将请求参数转变为request */ if (request == null) { throw new RequestLimitException("方法中缺失HttpServletRequest参数"); } String ip = (); String url = ().toString(); String key = "req_limit".concat(ip).concat(url); if ((key) == null || (key) == 0) { (key, 1); } else { (key, (key) + 1); } Integer count = (key); if (count > 0) { //创建一个定时器 Timer timer = new Timer(); TimerTask timerTask = new TimerTask() { @Override public void run() { (key); } }; //这个定时器设定在time规定的时间之后会执行上面的remove方法,也就是说在这个时间后它可以重新访问 (timerTask, ()); } if (count > ()) { ("用户IP[" + ip + "]访问地址[" + url + "]超过了限定的次数[" + () + "]"); throw new RequestLimitException(); } }catch (RequestLimitException e){ throw e; }catch (Exception e){ } } }
package ; import ; import ; import .*; @Retention() @Target() @Documented @Order(Ordered.HIGHEST_PRECEDENCE) public @interface RequestLimit { /** * 允许访问最大次数 */ int count() default Integer.MAX_VALUE; /** * 时间段 */ long time() default 6000; }
package ; import ; import ; import ; @Controller public class testController { @RequestMapping("/hello") @RequestLimit(count = 4, time = 60000) public String test(HttpServletRequest request) { return "hello1111"; } }