Spring Boot拦截器(Interceptor)详解

这篇具有很好参考价值的文章主要介绍了Spring Boot拦截器(Interceptor)详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Interceptor 介绍

**拦截器(Interceptor)**同 Filter 过滤器一样,它俩都是面向切面编程——AOP 的具体实现(AOP切面编程只是一种编程思想而已)。

你可以使用 Interceptor 来执行某些任务,例如在 Controller 处理请求之前编写日志,添加或更新配置……

Spring中,当请求发送到 Controller 时,在被Controller处理之前,它必须经过 Interceptors(0或多个)。

Spring Interceptor是一个非常类似于Servlet Filter 的概念 。

Interceptor 作用

  1. 日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算 PV(Page View)等;
  2. 权限检查:如登录检测,进入处理器检测是否登录;
  3. 性能监控:通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间。(反向代理,如 Apache 也可以自动记录)
  4. 通用行为:读取 Cookie 得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取 Locale、Theme 信息等,只要是多个处理器都需要的即可使用拦截器实现。

自定义 Interceptor

如果你需要自定义 Interceptor 的话必须实现 org.springframework.web.servlet.HandlerInterceptor接口或继承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter类,并且需要重写下面下面 3 个方法:

public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {

	/**
	 * This implementation always returns {@code true}.
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return true;
	}

	/**
	 * This implementation is empty.
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {
	}

	/**
	 * This implementation is empty.
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
	}

	/**
	 * This implementation is empty.
	 */
	@Override
	public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response,
			Object handler) throws Exception {
	}

}
  1. preHandler(HttpServletRequest request, HttpServletResponse response, Object handler) 方法在请求处理之前被调用。该方法在 Interceptor 类中最先执行,用来进行一些前置初始化操作或是对当前请求做预处理,也可以进行一些判断来决定请求是否要继续进行下去。该方法的返回至是 Boolean 类型,当它返回 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行;当它返回为 true 时会继续调用下一个 Interceptor 的 preHandle 方法,如果已经是最后一个 Interceptor 的时候就会调用当前请求的 Controller 方法。

  2. postHandler(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 方法在当前请求处理完成之后,也就是 Controller 方法调用之后执行,但是它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。

  3. afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法需要在当前对应的 Interceptor 类的 preHandle 方法返回值为 true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行。此方法主要用来进行资源清理。

接下来结合实际代码进行学习。

LogInterceptor 类:

public class LogInterceptor extends HandlerInterceptorAdapter {    

@Override    
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {      
     long startTime = System.currentTimeMillis();       
     System.out.println("\n-------- LogInterception.preHandle --- ");        
     System.out.println("Request URL: " + request.getRequestURL());        
     System.out.println("Start Time: " + System.currentTimeMillis());        
     request.setAttribute("startTime", startTime);       
      return true;    
}    

@Override   
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 
      System.out.println("\n-------- LogInterception.postHandle --- ");        
      System.out.println("Request URL: " + request.getRequestURL());    
}    

@Override   
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {        
   System.out.println("\n-------- LogInterception.afterCompletion --- ");        
   long startTime = (Long) request.getAttribute("startTime");        
   long endTime = System.currentTimeMillis();        
   System.out.println("Request URL: " + request.getRequestURL());        
   System.out.println("End Time: " + endTime);        
   System.out.println("Time Taken: " + (endTime - startTime));   
    }
}

OldLoginInterceptor 类:

public class OldLoginInterceptor extends HandlerInterceptorAdapter {
@Override    
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {       
	    System.out.println("\n-------- OldLoginInterceptor.preHandle --- ");       
	    System.out.println("Request URL: " + request.getRequestURL());      
	    System.out.println("Sorry! This URL is no longer used, Redirect to /admin/login");        	   response.sendRedirect(request.getContextPath()+ "/admin/login");      
	    return false;   
}

@Override    
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {        
	System.out.println("\n-------- OldLoginInterceptor.postHandle --- ");    
}   

@Override    
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {        
	System.out.println("\n-------- OldLoginInterceptor.afterCompletion --- ");    
	}

}

配置拦截器 :

@Configurationpublic 
class WebConfig implements WebMvcConfigurer {    
@Override    
public void addInterceptors(InterceptorRegistry registry) {        
	registry.addInterceptor(new LogInterceptor());      
	registry.addInterceptor(new OldLoginInterceptor()).addPathPatterns("/admin/oldLogin"); 
	registry.addInterceptor(new	AdminInterceptor()).addPathPatterns("/admin/*").excludePathPatterns("/admin/oldLogin");   
	 }
}

LogInterceptor 拦截器用于拦截所有请求; OldLoginInterceptor 用来拦截链接 “ / admin / oldLogin”,它将重定向到新的 “ / admin / login”。;AdminInterceptor用来拦截链接 “/admin/*”,除了链接 “ / admin/oldLogin”。

自定义 Controller 验证拦截器

@Controllerpublic 
class LoginController {    
	@RequestMapping("/index")    
	public String index(Model model){        
		return "index";   
	 }   
	  
	@RequestMapping(value = "/admin/login")    
	public String login(Model model){        
		return "login";   
	 }
}

拦截器顺序

spring中拦截器执行顺序:

多个拦截器顺序:

  1. 默认的注册顺序
  2. InterceptorRegistry#order(int)方法指定顺序,值越小优先级越高

拦截器1

public class PathInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("PathInterceptor 执行");
        System.out.println("第一个执行的拦截器,进行权限校验。巴拉巴拉、、、、");
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("PathInterceptor afterCompletion 完成");
    }
}

拦截器2

public class TestInterceptor implements HandlerInterceptor {

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      System.out.println("TestInterceptor 执行");
      System.out.println("第二个执行的拦截器。巴拉巴拉、、、、");
      return true;
  }

  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
      System.out.println("TestInterceptor  afterCompletion 完成");
  }
}

默认情况下,拦截器按照注册的顺序执行:

    @Bean
    public TestInterceptor testInterceptor() {
        return new TestInterceptor();
    }

    @Bean
    public PathInterceptor pathInterceptor() {
        return new PathInterceptor();
    }


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(testInterceptor()).addPathPatterns("/**");
        registry.addInterceptor(pathInterceptor()).addPathPatterns("/**");
    }

输出:

 TestInterceptor 执行
 第二个执行的拦截器。巴拉巴拉、、、、
 PathInterceptor 执行
 第一个执行的拦截器,进行权限校验。巴拉巴拉、、、、
 PathInterceptor afterCompletion 完成
 TestInterceptor  afterCompletion 完成

通过面向百度编程发现

  • 可以使用 @Order 注解定义顺序
  • 实现Ordered接口
    测试发现都不生效,注解无论放到拦截器类上还是放到@Bean注解的位置都无效

解决方法

注册拦截器时,使用 InterceptorRegistry#order(int) 方法指定顺序,值越小优先级越高。

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(testInterceptor()).addPathPatterns("/**").order(2);
        registry.addInterceptor(pathInterceptor()).addPathPatterns("/**").order(1);
    }

输出:文章来源地址https://www.toymoban.com/news/detail-436484.html

PathInterceptor 执行
第一个执行的拦截器,进行权限校验。巴拉巴拉、、、、
TestInterceptor 执行
第二个执行的拦截器。巴拉巴拉、、、、
TestInterceptor  afterCompletion 完成
PathInterceptor afterCompletion 完成

到了这里,关于Spring Boot拦截器(Interceptor)详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • interceptor拦截器框架

    在实际开发中,我们可能需要拦截部分请求进行一些额外的处理,比如校验用户权限、记录请求日志等。而在Spring Boot中,使用拦截器(Interceptors)可以很方便地对请求进行拦截处理。 首先需要定义一个拦截器,通常需要实现HandlerInterceptor接口,并重写其中的方法: java @Co

    2023年04月16日
    浏览(51)
  • 【SpringBoot篇】Interceptor拦截器 | 拦截器和过滤器的区别

    拦截器(Interceptor)是一种软件设计模式,用于在应用程序处理请求或响应时对其进行拦截和修改。拦截器可以在整个应用程序中使用,用于执行跨越多个层的通用任务,如身份验证、授权、缓存、日志记录、性能计量等。 在Web开发中,拦截器通常用于在请求到达控制器之前

    2024年02月04日
    浏览(59)
  • SpringMVC拦截器 (Interceptor)

            Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、判断用户是否登录等。         拦截器依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的

    2024年01月22日
    浏览(46)
  • 【Spring Boot系列】- Spring Boot拦截器

    拦截器(Interceptor)是在面向切面编程中应用的,就是在service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制。可以根据 URL 对请求进行拦截,主要应用于登陆校验、权限验证、乱码解决、性能监控和异常处理等功能。 在 Spring Boot 项目中,

    2024年02月13日
    浏览(38)
  • spring boot 拦截器例子

    在Spring Boot中,拦截器是通过实现`HandlerInterceptor`接口来实现的。它允许你在请求到达控制器方法之前和之后执行自定义的逻辑。下面我将为你提供一个简单的Spring Boot拦截器的例子。 假设我们有一个简单的控制器类`UserController`,其中有两个请求处理方法:`getUser`和`saveUser`,

    2024年02月15日
    浏览(38)
  • Spring Boot 配置拦截器

    通过拦截器,我们可以针对特定 URI 做拦截,做相关业务处理,比如检查用户是否登录,打印每个请求的处理耗时等。 新建登录验证类  LoginValidationInterceptor.java : 定义一个拦截器类后,您需要实现  HandlerInterceptor  接口,其有三个方法可以重写: preHandle : 在调用 Controller 方

    2024年02月08日
    浏览(56)
  • SpringBoot(八)拦截器Interceptor

        上篇介绍了Filter过滤器的使用,提起过滤器,就不得不再提起另外一个叫做拦截器的东西。两者的作用类似,都可以实现拦截请求的作用,但其实两者有着非常大的区别。本篇,我们就来学习下拦截器的使用。     如果你是新手,且没看过我之前的一系列SpringBoot文章,

    2024年02月17日
    浏览(41)
  • SpringMVC的拦截器(Interceptor)

    对于拦截器这节的知识,我们需要学习如下内容: 拦截器概念 入门案例 拦截器参数 拦截器工作流程分析 讲解拦截器的概念之前,我们先看一张图: (1)浏览器发送一个请求会先到Tomcat的web服务器 (2)Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源 (3)如果是

    2024年02月09日
    浏览(40)
  • 【SpringBoot】拦截器(Interceptor)的使用

            拦截器(Interceptor)是一种特殊的组件,它可以在请求处理的过程中对请求和响应进行拦截和处理。拦截器可以在请求到达目标处理器之前、处理器处理请求之后以及视图渲染之前执行特定的操作。拦截器的主要目的是在不修改原有代码的情况下,实现对请求和响

    2024年02月04日
    浏览(44)
  • Spring Boot统一处理功能——拦截器

    ⽤户登录权限的发展从之前每个⽅法中⾃⼰验证⽤户登录权限,到现在统⼀的⽤户登录验证处理,它是⼀个逐渐完善和逐渐优化的过程。 我们先来回顾⼀下最初⽤户登录验证的实现⽅法: 从上述代码可以看出,每个⽅法中都有相同的⽤户登录验证权限,它的缺点是: 1. 每个

    2024年02月13日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包