buc算法java实现,用Redis解决接口防刷的问题

/**

* 请求拦截*/@Slf4j

@Componentpublic classRequestLimitIntercept extends HandlerInterceptorAdapter {

@Autowiredprivate RedisTemplateredisTemplate;

@Overridepublicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {/**

* isAssignableFrom() 判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口

* isAssignableFrom()方法是判断是否为某个类的父类

* instanceof关键字是判断是否某个类的子类*/

if(handler.getClass().isAssignableFrom(HandlerMethod.class)){//HandlerMethod 封装方法定义相关的信息,如类,方法,参数等

HandlerMethod handlerMethod =(HandlerMethod) handler;

Method method=handlerMethod.getMethod();//获取方法中是否包含注解

RequestLimit methodAnnotation = method.getAnnotation(RequestLimit.class);//获取 类中是否包含注解,也就是controller 是否有注解

RequestLimit classAnnotation = method.getDeclaringClass().getAnnotation(RequestLimit.class);//如果 方法上有注解就优先选择方法上的参数,否则类上的参数

RequestLimit requestLimit = methodAnnotation != null?methodAnnotation:classAnnotation;if(requestLimit != null){if(isLimit(request,requestLimit)){

resonseOut(response,Result.error(ApiResultEnum.REQUST_LIMIT));return false;

}

}

}returnsuper.preHandle(request, response, handler);

}//判断请求是否受限

publicboolean isLimit(HttpServletRequest request,RequestLimit requestLimit){//受限的redis 缓存key ,因为这里用浏览器做测试,我就用sessionid 来做唯一key,如果是app ,可以使用 用户ID 之类的唯一标识。

String limitKey = request.getServletPath()+request.getSession().getId();//从缓存中获取,当前这个请求访问了几次

Integer redisCount = (Integer) redisTemplate.opsForValue().get(limitKey);if(redisCount == null){//初始 次数

redisTemplate.opsForValue().set(limitKey,1,requestLimit.second(), TimeUnit.SECONDS);

}else{if(redisCount.intValue() >=requestLimit.maxCount()){return true;

}//次数自增

redisTemplate.opsForValue().increment(limitKey);

}return false;

}/**

* 回写给客户端

* @param response

* @param result

* @throws IOException*/

private voidresonseOut(HttpServletResponse response, Result result) throws IOException {

response.setCharacterEncoding("UTF-8");

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

PrintWriterout = null;

String json=JSONObject.toJSON(result).toString();out =response.getWriter();out.append(json);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值