springboot自定义拦截器拦截所有请求,springboot拦截器配置不拦截

  springboot自定义拦截器拦截所有请求,springboot拦截器配置不拦截

  00-1010 1.Spring Boot第二版。什么是截击机3。工作原则4。拦截器的工作流4.1正常进程4.2中断进程5。应用场景6。如何定制一个拦截器7?如何使它在Spring Boot 8有效?实际使用8.1情景模拟8.2思路8.3实施过程8.4效果体验9。摘要

  

目录

基于本文的Spring Boot版本是2.6.7。

 

  

1.SpringBoot版本

Spring MVC中的拦截器类似于ServLet中的过滤器,主要用于拦截用户请求并进行相应的处理。比如拦截器可以验证权限,记录请求信息的日志,判断用户是否登录。

 

  00-1010一个拦截器,只有preHandle方法返回true时,才能执行postHandle和afterCompletion如果preHandle方法返回false,将不会执行拦截器的postHandle和afterCompletion。拦截器不是过滤器,但它实现了过滤器的功能。其原理在于:

  1.所有拦截器和处理程序都在HandlerMapping中注册。

  2.2号房的所有请求。Spring MVC由DispatcherServlet分发。

  3.当请求进入DispatcherServlet.doDispatch()时,您将首先获得处理请求的处理程序(即控制器中对应的方法)和所有拦截请求的拦截器。这是拦截器被调用并开始工作的地方。

  

2.什么是拦截器

 

  

3.工作原理

 

  00-1010如果在Interceptor1.preHandle中报告了一个错误或者返回了false,那么下一个进程将会被中断,但是注意已经执行的拦截器的afterCompletion仍然会被执行。

  00-1010拦截器本质上是面向方面编程(AOP),所有满足横切关注点的功能都可以在拦截器中实现。主要应用场景包括:

  登录,以确定用户是否已登录。权限验证,确定用户是否有访问资源的权限,比如验证令牌日志,记录请求操作日志(用户ip,访问时间等。),以便统计请求的数量。处理cookie、本地化、国际化、主题等。性能监控、监控请求处理时间等。

  00-1010定制一个拦截器非常简单。您只需要实现HandlerInterceptor接口。有三种方法可以实现该接口,如下所示:

  Pre-handle()方法:方法改变会在控制方法之前执行,控制器的返回值表示你是否知道如何写一个接口。中断后续操作。返回值为真时,表示执行继续向下;当其返回值为false时,会中断所有后续操作(包括调用下一个拦截器和控制器类中的方法执行等。).postHandle()方法将在调用控制器方法之后、解析视图之前执行。您可以通过这种方法对请求域中的模型和视图进行进一步的修改。AfterCompletion()方法:该方法将在整个请求完成后,也就是视图渲染完成后执行。这个方法可以用来清理一些资源和记录日志信息。

  00-1010实际上想在Spring Boot生效。其实很简单。只需要定义一个配置类,实现WebMvcConfigurer接口,并在其中实现addInterceptiors()方法。代码演示如下:

  @Configurationpublic类WebConfig实现webmvc configurer { @ auto wired private XXX XXX;@Ove

  rride public void addInterceptors(InterceptorRegistry registry) { //不需要拦截的url final String[] commonExclude={}; registry.addInterceptor(xxx).excludePathPatterns(commonExclude) }}

 

  

8.实际使用

 

  

8.1场景模拟

通过拦截器防止用户暴力请求连接,使用用户IP来限制访问次数 。达到多少次数禁止该IP访问。

 

  

 

  

8.2思路

记录用户IP访问次数,第一次访问时在redis中创建一个有效时长1秒的key,当第二次访问时key值+1,当值大于等于5时在redis中创建一个5分钟的key,当拦截器查询到reids中有当前IP的key值时返回false限制用户请求接口 。

 

  

 

  

8.3实现过程

第一步,创建一个拦截器,代码如下:

 

  

@Slf4jpublic class IpUrlLimitInterceptor implements HandlerInterceptor { @Resource RedisUtils redisUtils; private static final String LOCK_IP_URL_KEY="lock_ip_"; private static final String IP_URL_REQ_TIME="ip_url_times_"; //访问次数限制 private static final long LIMIT_TIMES=5; //限制时间 秒为单位 private static final int IP_LOCK_TIME=300; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("request请求地址uri={},ip={}",request.getRequestURI(), IpUtils.getRequestIP(request)); if(ipIsLock(IpUtils.getRequestIP(request))){ log.info("ip访问被禁止={}",IpUtils.getRequestIP(request)); throw new Exception("当前操作过于频繁,请5分钟后重试"); } if (!addRequestTime(IpUtils.getRequestIP(request),request.getRequestURI())){ log.info("当前{}操作过于频繁,请5分钟后重试",IpUtils.getRequestIP(request)); throw new Exception("当前操作过于频繁,请5分钟后重试"); } return true; } private boolean addRequestTime(String ip, String uri) { String key = IP_URL_REQ_TIME+ip+uri; if(redisUtils.hasKey(key)){ long time=redisUtils.incr(key,(long)1); if(time >=LIMIT_TIMES){ redisUtils.set(LOCK_IP_URL_KEY+ip,IP_LOCK_TIME); return false; } }else { boolean set = redisUtils.set(key, (long) 1, 1); } return true; } private boolean ipIsLock(String ip) { if(redisUtils.hasKey(LOCK_IP_URL_KEY+ip)){ return true; } return false; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { HandlerInterceptor.super.afterCompletion(request, response, handler, ex); }}

第二步,定义一个获取IP的工具类,代码如下:

 

  

@Slf4jpublic class IpUtils { public static String getRequestIP(HttpServletRequest request){ String ip = request.getHeader("x-forwarded-for"); if(ip != null && ip.length() !=0 && "unknown".equalsIgnoreCase(ip)){ // 多次反向代理后会有多个ip值,第一个ip才是真实ip if( ip.indexOf(",")!=-1 ){ ip = ip.split(",")[0]; } } if (ip == null ip.length() == 0 "unknown".equalsIgnoreCase(ip)){ ip = request.getHeader("Proxy-Client-IP"); log.info("Proxy-Client-IP ip: " + ip); } if (ip == null ip.length() == 0 "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); log.info("HTTP_CLIENT_IP ip: " + ip); } if (ip == null ip.length() == 0 "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); log.info("HTTP_X_FORWARDED_FOR ip: " + ip); } if (ip == null ip.length() == 0 "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("X-Real-IP"); log.info("X-Real-IP ip: " + ip); } if (ip == null ip.length() == 0 "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); log.info("getRemoteAddr ip: " + ip); } return ip; }}

第二步,在Spring Boot中配置这个拦截器,代码如下:

 

  

@Configurationpublic class WebConfig implements WebMvcConfigurer { @Bean IpUrlLimitInterceptor getIpUrlLimitInterceptor(){ return new IpUrlLimitInterceptor(); }; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(getIpUrlLimitInterceptor()).addPathPatterns("/**"); }}

 

  

8.4效果体验

 

  

 

  

9.总结

该拦截器是全局生效的,可能有些场景某个接口不需要限制,这样我们可以把这个拦截器改造成注解方式应用。某些接口需要则加上注解即可。

 

  以上就是详解SpringBoot中自定义和配置拦截器的方法的详细内容,更多关于SpringBoot拦截器的资料请关注盛行IT其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: