SpringBoot-Interceptor详解
拦截器(Interceptor)与过滤器(Filter)类似,是面向切面编程的一种具体实现。你可以使用拦截器执行某些任务,比如在控制器处理请求前记录日志、更新配置等。在 Spring 中,当请求发送到控制器时,在被控制器处理之前,它必须经过拦截器。
拦截器与过滤器的区别
拦截器(Interceptor)和过滤器(Filter)的主要区别在于作用范围和实现方式。
作用范围
- 过滤器作用于整个 Web 应用程序,可以过滤所有请求和响应。它是 Servlet 规范的一部分,由 Servlet 容器管理。
- 拦截器通常作用于特定框架。比如,在 Spring Boot 中,它主要拦截特定框架的请求处理流程,并在特定框架内处理请求。
实现方式
- 过滤器实现 javax.servlet.Filter 接口,并在 web.xml 中或通过注解进行配置。需要实现 init()、doFilter() 和 destroy() 等方法。
- 拦截器在不同框架中有不同的实现方式。比如,在 Spring MVC 中,可以实现 HandlerInterceptor 接口或继承 HandlerInterceptorAdapter 类。需要实现 preHandle()、postHandle() 和 afterCompletion() 等方法。
拦截器的作用
- 登录验证和访问控制:拦截器可用于检查用户的登录状态和权限,并根据需要执行相关处理。比如,可以使用拦截器验证用户的登录状态。如果未登录,则重定向到登录页面或返回相应的错误信息。
- 异常处理和统一错误处理:拦截器可以捕获并处理请求处理过程中发生的异常。可以根据异常类型执行适当的处理,比如返回自定义错误页面或错误信息,或执行特定的错误处理逻辑。当然,它还有许多其他应用场景,这里不再一一列举
自定义拦截器
自定义拦截器的话,需要实现HandlerInterceptor 接口或继承HandlerInterceptorAdapter 类,并且需要重写以下三个方法:
1.preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):此方法在请求处理之前调用。该方法在拦截器类中首先执行,用于一些预初始化操作或对当前请求进行预处理。你还可以进行一些判断,以确定请求是否应该继续。此方法的返回值为布尔类型。当它返回 false 时,表示请求结束,后续的拦截器和控制器将不再执行。当它返回 true 时,将调用下一个拦截器的 preHandle 方法。如果已经是最后一个拦截器,则将调用当前请求的控制器方法。
2.postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView):此方法在当前请求处理完成后执行,即在控制器方法被调用之后。但是,它将在 DispatcherServlet 渲染视图之前被调用。因此,我们可以在此方法中在控制器处理后对 ModelAndView 对象进行操作。
3.afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex):只有当相应拦截器类的 postHandle 方法的返回值为 true 时,此方法才会执行。顾名思义,此方法将在整个请求结束后执行,即在 DispatcherServlet 渲染相应视图之后。此方法主要用于资源清理。
用户登录权限验证
1.自定义拦截器
1 |
|
2.将自定义拦截器添加到系统配置中
1 |
|
在配置类中,重写 addInterceptors 方法。此方法用于注册拦截器。在这里,通过调用 InterceptorRegistry 的 addInterceptor 方法添加拦截器,并设置拦截路径和排除路径。
具体来说,通过调用 addInterceptor(loginInterceptor) 添加 LoginInterceptor 拦截器。然后使用 addPathPatterns 方法指定需要拦截的 URL 路径模式。这里,“/**”用于表示拦截所有 URL。使用 excludePathPatterns 方法排除一些不会被拦截的特定 URL 路径。
3.用户控制器
1 |
|
分别访问3个接口的结果如下:


添加统一访问前缀
在 WebMvcConfigurer 接口中,configurePathMatch 方法用于配置路径匹配规则。这里我们给所有请求地址添加前缀“pre”。
1 |
|
在这个例子中,传递给 addPathPrefix 方法的前缀是“pre”,Predicate 对象是一个实现了 Predicate<Class<?>>接口的匿名内部类。Predicate 接口是 Java 8 中引入的一个函数式接口,其 test 方法用于判断传入的类是否满足条件。
在这个匿名内部类中,重写 test 方法使其始终返回 true,这意味着所有类都满足条件,并且将添加统一的访问前缀。
因此,通过这段代码的配置,所有请求路径都将在前面添加“pre”前缀。比如,如果原始路径是“example”,添加前缀后的路径变为“/pre/example”。这样可以实现对请求路径的统一处理。
注意:如果添加了前缀,拦截器的排除路径也应该相应更改。
1 |
|
配置本地资源映射路径
实现 WebMvcConfigurer 接口并重写 addResourceHandlers(ResourceHandlerRegistry registry) 方法,其中:
- addResourceHandler() 添加访问路径;
- addResourceLocations() 添加映射的真实路径。映射的真实路径末尾必须跟“/”,否则无法映射。“/”在 Windows 和 Linux 中都适用。
1 | // D:/test/ |
这段代码将配置一个拦截器。如果访问路径是 addResourceHandler 中的路径,那么它将被映射到 addResourceLocations 参数中的路径。这样,其他人就可以访问服务器上的本地文件,如本地图片或本地音乐视频。
参考文档
作者:写bug写bug
链接:https://juejin.cn/post/7499441782163898406
来源:稀土掘金