赞
踩
针对耗时操作的接口,避免在短时间内重复请求,在后端用拦截器对请求进行拦截过滤,判断请求频率是否在合理时间范围内。
- @Component
- public class RequestFrequenceInterceptor implements HandlerInterceptor {
- private static Logger log = LoggerFactory.getLogger( RequestFrequenceInterceptor.class );
-
- private long lastTime = 0;
- private boolean startDelay(int time) {
- long currentTime = System.currentTimeMillis();
- if (currentTime - lastTime > time) {
- System.out.println(currentTime + " - " + lastTime);
- lastTime = currentTime;
- return true;
- }
-
- return false;
- }
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-
- String ip = CommontMethod.getIpAddr( request );//获取ip地址
- //开始进入请求地址拦截
- //获取执行方法上的注解 不过滤静态资源
- if(handler instanceof HandlerMethod){
- HandlerMethod hm = (HandlerMethod) handler;
- //对包含注解的方法进行频率验证
- Delay delay = hm.getMethodAnnotation(Delay.class);
- if (delay != null) {
- if ( startDelay(delay.time()))
- {
- return true;
- }else {
- log.warn( ip+" 请求频率过快" );
- Map<String,Object> responseMap = new HashMap<>( );
- responseMap.put( "code", SystemCode.LOCK_USER.getCode() );
- responseMap.put( "message","请求被锁定,频率过快" );
- String resStr = JsonUtil.toJsonStr(responseMap);
- response.setContentType("application/json;charset=utf-8");
- response.setHeader("Access-Control-Allow-Origin", "*");
- response.setHeader("Cache-Control","no-cache");
- response.getWriter().write(resStr);
-
- return false;
- }
- }
- }
-
-
-
- // 对于不包含注解的方法一律放行
- return true;
-
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
- //处理请求完成后紧接着的操作
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
- //视图渲染之后的操作
- }
- }

- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.RUNTIME)
- @Component
- public @interface Delay {
- //默认两秒,意思是每个方法两秒内只能请求一次,重复请求无效
- int time() default 2000;
-
- }
- @Configuration
- public class RequestParamInterceptorConf implements WebMvcConfigurer {
- @Autowired
- RequestParamInterceptor requestParamInterceptor;
- @Autowired
- RequestFrequenceInterceptor frequenceInterceptor;
- @Override
- public void addInterceptors(InterceptorRegistry registry){
- // 多个拦截器组成一个拦截器链
- // addPathPatterns 用于添加拦截规则
- // excludePathPatterns 用户排除拦截
- // TokenInterceptor()为自己定义的拦截器
- registry.addInterceptor(requestParamInterceptor).addPathPatterns("/**").excludePathPatterns("/error");
- registry.addInterceptor( frequenceInterceptor ).addPathPatterns( "/**" ).excludePathPatterns("/error");
- }
- }

- public class CommontMethod {
-
- /**
- * 获取请求ip
- * @param request
- * @return
- */
- public static String getIpAddr(HttpServletRequest request){
- String ipAddress = request.getHeader("x-forwarded-for");
- if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
- ipAddress = request.getHeader("Proxy-Client-IP");
- }
- if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
- ipAddress = request.getHeader("WL-Proxy-Client-IP");
- }
- if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
- ipAddress = request.getRemoteAddr();
- if("127.0.0.1".equals(ipAddress) || "0:0:0:0:0:0:0:1".equals(ipAddress)){
- //根据网卡取本机配置的IP
- InetAddress inet=null;
- try {
- inet = InetAddress.getLocalHost();
- } catch (UnknownHostException e) {
- e.printStackTrace();
- }
- ipAddress= inet.getHostAddress();
- }
- }
- //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
- if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
- if(ipAddress.indexOf(",")>0){
- ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
- }
- }
- return ipAddress;
- }
-
- }

总结:要使用该注解,直接在要使用的方法上@Dely(value=5000)即可
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。