# 拦截器
# 拦截器概念

拦截器 (Interceptor) 是一种动态拦截方法调用的机制,在 SpringMvc 中动态拦截控制器方法的执行
作用:
- 在指定的方法调用前后执行预先设定的代码
- 阻止原始方法的执行
# 拦截器与过滤器区别
归属不同:Filter 属于 Servlet 技术,Interceptor 属于 SpringMvc 技术
拦截内容不同:Filter 对所有访问进行增强,Interceptor 仅针对 SpringMvc 的访问进行增强
# 入门案例
- 制作拦截器功能类
- 生命拦截器的 bean, 并实现 HandlerInterceptor 接口 (注意:扫描加载 bean)
@SuppressWarnings("all") | |
@Component | |
public class ProjectInterceptor implements HandlerInterceptor { | |
@Override | |
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | |
System.out.println("preHandler ..."); | |
// 改为 false 将终止原始操作的执行,如果终止了原始操作那么后面的方法也不会被执行 | |
return true; | |
} | |
@Override | |
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { | |
System.out.println("postHandler ..."); | |
} | |
@Override | |
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { | |
System.out.println("afterHandler ..."); | |
} | |
} |
- 定义配置类,继承 WebMvcConfigurationSupport, 实现 addInterceptor 方法 (注意:扫描加载配置)
@SuppressWarnings("all") | |
// 配置 bean | |
@Configuration | |
public class SpringMvcSupport extends WebMvcConfigurationSupport { | |
@Override | |
protected void addResourceHandlers(ResourceHandlerRegistry registry) { | |
... | |
} | |
} |
addResourceHandlers 的详细介绍:
SpringBoot 中,addResourceHandlers 方法用于配置静态资源的方式。通过该方法,你可以指定哪些路径下的静态资源应该被处理,以及如何处理它们。这些静态资源通常包括 CSS 文件,JavaScript 文件,图像文件等。
addResourceHandlers 方法详解:
addResourceHandlers 方法定义在 WebMvcConfigurer 接口中,用于自定义 SpringMVC 的配置。你可以通过实现 WebMvcConfigurer 接口并覆盖 addResourceHandlers 方法来配置资源处理器,以下是一个示例,展示了如何配置静态资源处理:
import org.springframework.context.annotation.Configuration; | |
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; | |
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | |
@Configuration | |
public class WebConfig implements WebMvcConfigurer { | |
@Override | |
public void addResourceHandlers(ResourceHandlerRegistry registry) { | |
// 将请求路径 /static/** 映射到类路径下的 /static/ 目录 | |
registry.addResourceHandler("/static/**") | |
.addResourceLocations("classpath:/static/") | |
.setCachePeriod(3600) // 设置缓存时间为 3600 秒 | |
.resourceChain(true); // 启用资源链优化 | |
} | |
} |
关键配置选项:
- addResourceHandler(String... pathPatterns)
- 该方法用于指定应该拦截的 URL 路径模式。例如:/static/** 表示拦截所有以 /static/ 开头的请求
- addResourceLocations(String... resourceLocations)
- 该方法用于指定静态资源的存储位置。可以是文件系统路径 (file:/path/to/resources/) 或类路径 (classpath:/static)
- setCachePeriod(int cachePeriod)
- 设置缓存时间 (以秒为单位)。例如,3600 表示资源缓存时间为 1 小时
- resourceChain(boolean enabled)
- 启用或禁用资源链优化。资源链优化可以提高静态资源的解析和处理效率
常见的资源处理配置
类路径资源
如果静态资源存储在项目的类路径中(如 src/main/resources/static),可以使用 classpath: 前缀来指定资源位置
registry.addResourceHandler("/resources/**")
.addResourceLocations("classpath:/static/");
文件系统资源
如果静态资源存储在文件系统中,可以使用 file: 前缀来指定资源位置
registry.addResourceHandler("/files/**")
.addResourceLocations("file:/opt/files/");
多路径映射
可以将多个路径模式映射多个资源位置
registry.addResourceHandler("/images/**")
.addResourceLocations("classpath:/static/images/", "file:/opt/images/");
作用
- 静态资源处理
- addResourceHandlers 方法允许你定义如何处理静态请求,使得这些请求可以被正确路由到相应的资源文件
- 缓存控制
- 通过设置缓存时间,可以提高静态资源的加载速度,减少服务器的负载
- 资源链优化
- 资源链优化可以提高静态资源的解析和处理效率
使用场景
web 应用
- 在 web 应用中通常需要处理大量的静态资源,例如 CSS, JavaScript 和图像文件。通过配置 addResourceHandlers ,可以确保这些资源被正确处理并提供给客户端
API 服务
- 虽然 API 服务主要提供数据接口,但有时也需要提供静态资源,例如 API 文档。此时也可以使用 addResourceHandlers 来配置静态资源的处理
添加拦截器并设定拦截的访问路径,路径可以通过可变参数设置多个
@SuppressWarnings("all") | |
// 配置 bean | |
@Configuration | |
public class SpringMvcSupport extends WebMvcConfigurationSupport { | |
@Autowired | |
private ProjectInterceptor projectinterceptor; | |
@Override | |
protected void addResourceHandlers(ResourceHandlerRegistry registry) { | |
... | |
} | |
@Override | |
protected void addInterceptors(InterceptorRegistry registry) { | |
// 先设置加哪个拦截器,在设置拦截哪个请求 | |
registry.addInterceptor(projectinterceptor).addPathPatterns("/books","/books/*"); | |
} | |
} |
- 使用标准接口 WebMvcConfigurer 简化开发 (注意:入侵式较强)
@SuppressWarnings("all") | |
@Configuration | |
@ComponentScan({"com.dkx.spring.controller"}) | |
@EnableWebMvc | |
public class SpringMvcConfig implements WebMvcConfigurer { | |
@Autowired | |
private ProjectInterceptor projectinterceptor; | |
@Override | |
public void addInterceptors(InterceptorRegistry registry) { | |
registry.addInterceptor(projectinterceptor).addPathPatterns("/books"); | |
} | |
} |

# 拦截器参数
# 前置处理
@SuppressWarnings("all") | |
@Component | |
public class ProjectInterceptor implements HandlerInterceptor { | |
@Override | |
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | |
System.out.println("preHandler ..."); | |
// 改为 false 将终止原始操作的执行,如果终止了原始操作那么后面的方法也不会被执行 | |
return true; | |
} | |
} |
参数
- request: 请求对象
- response: 响应对象
- handler: 被调用的处理对象,本质上是一个方法对象,对反射技术中的 Method 对象进行了包装
返回值
- 返回值为 false, 被拦截的处理器将不执行
可以这么认为,拿到了 Handle 对象就可以操作原始执行的方法了
# 后置处理
@Override | |
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { | |
System.out.println("postHandler ..."); | |
} |
- 参数
- modelAndView: 如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整
# 完成后处理
@Override | |
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { | |
System.out.println("afterHandler ..."); | |
} |
- 参数
- ex: 如果处理器执行过程中出现异常对象,可以针对异常情况进行单独处理
# 拦截器执行顺序
当配置多个拦截器时,形成拦截器链
拦截器链的运行顺序参按照拦截器添加顺序为准
当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行
当拦截器运行中断,仅运行配置在前面的拦截器的 afterCompletion 操作

- 拦截器链的运行顺序
preHandle: 与配置顺序相同,必定运行
postHandlr: 与配置顺序相反,可能不运行
afterCompletion: 与配置顺序相反,可能不运行