一、问题描述
在使用Spring Boot 2.x开发项目时,我们可能会遇到一个问题,即静态资源(如CSS、JS、图片等)会被拦截器拦截而无法正常加载导致页面样式、交互等异常。这是因为Spring Boot 2.x采用了不同于之前版本的WebMvcConfigurerAdapter配置方式,在配置拦截器时需要特别注意。
二、原因分析
在Spring Boot 1.x及早期版本中,我们可以通过继承WebMvcConfigurerAdapter类并实现addInterceptors()方法来配置拦截器,例如:
@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
但是在Spring Boot 2.x中,WebMvcConfigurerAdapter已经被废弃,使用官方推荐的方式需要实现WebMvcConfigurer接口,例如:
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
WebMvcConfigurer.super.addInterceptors(registry);
}
}
这里需要特别注意到addInterceptors()方法的第二个参数需要传入一个路径数组,当请求路径匹配路径数组中的某个路径时才会执行拦截器。如果没有配置路径数组,拦截器将拦截所有请求,包括静态资源请求。这就是静态资源被拦截器拦截的原因。
三、解决方案
解决方案很简单,就是在匹配路径时排除静态资源路径即可。总的来说,有两种解决方案:
- 在addInterceptors()方法中定义路径数组时排除静态资源路径。可以使用静态资源路径的前缀来过滤静态资源请求,例如:
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/static/**"); // 排除静态资源路径
WebMvcConfigurer.super.addInterceptors(registry);
}
}
这里“/static/**”是定义的静态资源路径前缀,它可以根据实际情况修改。
- 在WebMvcConfigurer配置类中重写addResourceHandlers()方法,手动配置静态资源路径,例如:
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
WebMvcConfigurer.super.addResourceHandlers(registry);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
WebMvcConfigurer.super.addInterceptors(registry);
}
}
这里使用了addResourceHandlers()方法手动配置了静态资源路径,“/static/**”是静态资源访问路径,而实际的静态资源所在路径则为“classpath:/static/”(即resources/static/目录)。这种方式需要手动配置静态资源路径,但可以更加灵活地控制静态资源的访问,同时避免了静态资源被拦截器拦截的问题。
四、示例
- 在addInterceptors()方法中排除静态资源路径
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**");
WebMvcConfigurer.super.addInterceptors(registry);
}
}
由于排除了"/static/**"路径,LoginInterceptor不会拦截静态资源请求。示例代码中的LoginInterceptor实现了简单的登录验证功能。
- 在WebMvcConfigurer配置类中手动配置静态资源路径
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
WebMvcConfigurer.super.addResourceHandlers(registry);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**");
WebMvcConfigurer.super.addInterceptors(registry);
}
}
由于手动配置了静态资源路径,LoginInterceptor也不会拦截静态资源请求。示例代码中的LoginInterceptor实现了简单的登录验证功能。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:spring boot 2.x静态资源会被拦截器拦截的原因分析及解决 - Python技术站