说明:使用了注解的方式进行对接口防刷的功能,非常高大上,本文章仅供参考
一,技术要点:springboot的基本知识,redis基本操作,
首先是写一个注解类:
接着就是在Interceptor拦截器中实现:
importcom.alibaba.fastjson.JSON;
importcom.example.demo.action.AccessLimit;
importcom.example.demo.redis.RedisService;
importcom.example.demo.result.CodeMsg;
importcom.example.demo.result.Result;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.stereotype.Component;
importorg.springframework.web.method.HandlerMethod;
importorg.springframework.web.servlet.handler.HandlerInterceptorAdapter;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.io.OutputStream;
@Component
publicclassFangshuaInterceptorextendsHandlerInterceptorAdapter{
@Autowired
privateRedisService redisService;
@Override
publicbooleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throwsException{
//判断请求是否属于方法的请求
if(handlerinstanceofHandlerMethod){
HandlerMethod hm = (HandlerMethod) handler;
//获取方法中的注解,看是否有该注解
AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
if(accessLimit ==null){
returntrue;
}
intseconds = accessLimit.seconds();
intmaxCount = accessLimit.maxCount();
booleanlogin = 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);
}elseif(count < maxCount){
//加1
redisService.incr(ak,key);
}else{
//超出访问次数
render(response,CodeMsg.ACCESS_LIMIT_REACHED);//这里的CodeMsg是一个返回参数
returnfalse;
}
}
returntrue;
}
privatevoidrender(HttpServletResponse response, CodeMsg cm)throwsException{
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();
}
}
网友评论