Scenes
The project built by SpringBoot needs to implement anti-brush restrictions on the open interface, and the specified number of times can be requested within a specified number of seconds for different interfaces.
For example, the following limits the interface to request at most one time per second.
Note:
Blog:
Overbearing rogue temperament blog_CSDN Blog-C#, Architecture Road, Blogger in SpringBoot
accomplish
1. Implementation idea
First, customize the annotation and add the fields of time interval and maximum number of requests.
Then the custom interceptor intercepts whether there is a custom annotation on the interception method, and if so, obtains the requested url and uses it as the key stored in redis, and the interval is used as redis
The expiration time of the key, each request is accumulated and stored in redis, and if it is judged that the maximum number of requests is exceeded within the validity period of the redis key, a response with frequent requests will be returned.
2. First, implement custom annotations
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AccessLimit {
/**
* 秒数时间区间(多少秒内)
* @return
*/
int seconds();
/**
* 最大请求次数
* @return
*/
int maxCount();
}
3. Then customize the interception to implement the HandlerInterceptor interface, and rewrite its preHandle method to implement the interception before the method request
import com.alibaba.fastjson.JSON;
import com.badao.demo.common.AjaxResult;
import com.badao.demo.constant.Constants;
import com.badao.demo.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.concurrent.TimeUnit;
@Component
public class FangshuaInterceptor implements HandlerInterceptor {
@Autowired
private RedisCache 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();
//获取请求的Url作为redis中存储的key
String key = request.getRequestURI();
//从redis中获取用户访问的次数
Integer count = redisService.getCacheObject(key);
if(count == null){
//第一次访问
redisService.setCacheObject(key,1,seconds, TimeUnit.SECONDS);
}else if(count < maxCount){
//加1
count+=1;
redisService.setCacheObject(key,count,seconds, TimeUnit.SECONDS);
}else{
//超出访问次数,则渲染响应结果
render(response);
return false;
}
}
return true;
}
/**
* 接口渲染
* @param response
* @throws Exception
*/
private void render(HttpServletResponse response)throws Exception {
response.setContentType("application/json;charset=UTF-8");
OutputStream out = response.getOutputStream();
String str = JSON.toJSONString(AjaxResult.error(Constants.CALL_TOO_OFEN));
out.write(str.getBytes("UTF-8"));
out.flush();
out.close();
}
}
Among them, RedisCache is an encapsulated tool class for operating redis
AjaxResult is the encapsulated response result entity.
Constants.CALL_TOO_OFEN is a constant class used to prompt that the request is too frequent.
The encapsulation of the above tool classes can refer to
If you follow the front-end and back-end separation version to teach you how to build the environment locally and run the project:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108465662
4. Then register the interceptor in springboot
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.WebMvcConfigurer;
/**
* 把intercepror 注册到springboot中
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private FangshuaInterceptor interceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor);
}
}
5. When using, add annotations to the interface method and specify the time and maximum number of requests
@AccessLimit(seconds = 1,maxCount = 1)
@GetMapping("/test")
public AjaxResult test(@RequestParam("mineApiCode") String mineApiCode)
The above parameter setting means that the maximum number of requests within 1 second is 1.