在一个 Spring Boot
项目中,实现了HandlerInterceptor
拦截器,按理由说所有的请求都会通过它,包括静态资源请求。但运行项目发现请求静态资源时没有经过它。遂分析:
1.实现 HandlerInterceptor
拦截器
首先定义一个TestInterceptor
实现 HandlerInterceptor
拦截器
public class TestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("有请求经过测试拦截器啦!");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
2.将测试拦截器匹配所有路径
在WebConfig
配置类中把TestInterceptor
注册到容器中,并设置好它的拦截路径为/**
,即所有资源都拦截
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TestInterceptor())
.addPathPatterns("/**");
}
}
这时虽然拦截路径设置了/**
,但是发现TestInterceptor
对静态资源没有起作用。
这时看看addInterceptors()
方法上的注释。
Add Spring MVC lifecycle interceptors for pre- and post-processing of controller method invocations. Interceptors can be registered to apply to all requests or be limited to a subset of URL patterns.
Note that interceptors registered here only apply to controllers and not to resource handler requests. To intercept requests for static resources either declare a MappedInterceptor bean or switch to advanced configuration mode by extending WebMvcConfigurationSupport and then override resourceHandlerMapping.
意思就是说它只对controller起作用,如果想对静态资源起作用,要么声明一个 MappedInterceptor bean,要么通过扩展 WebMvcConfigurationSupport 切换到高级配置模式,然后覆盖 resourceHandlerMapping。
比较简单的就是声明一个 MappedInterceptor (拦截器映射)
修改 WebConfig
不再继承WebMvcConfigurerAdapter
接口,也不用它的addInterceptors()
方法注册拦截器,而是直接配置一个拦截器映射MappedInterceptor
给它,在这个映射里添加我们写的测试拦截器和拦截路径
@Configuration
public class WebConfig {
@Bean
public MappedInterceptor getMappedInterceptor() {
return new MappedInterceptor(new String[] { "/**" }, new TestInterceptor());
}
}
总结
这个问题一般是老版本的springboot
出现的问题,新版本也已经淘汰掉WebMvcConfigurerAdapter
接口了,改用WebMvcConfigurer
接口,其addInterceptors()
方法已经兼容了 Controller请求 和 资源处理请求,对二者皆可拦截。
/**
* Add Spring MVC lifecycle interceptors for pre- and post-processing of
* controller method invocations and resource handler requests.
* Interceptors can be registered to apply to all requests or be limited
* to a subset of URL patterns.
*/
default void addInterceptors(InterceptorRegistry registry) {
}