三、解决Spring MVC拦截器导致静态资源访问失败(基于java注解配置)
前言
对于这个问题,我们准备了以下三种解决方案:
1、静态资源统一交由Servlet容器直接处理;
2、静态资源统一交由Spring MVC框架间接处理,再转交给Servlet容器处理;
3、静态资源统一交由Spring MVC框架直接处理;
从这3种解决方案中,处理静态资源的方式可以分为Servlet容器处理和Spring MVC框架处理。在这里要说明的是,只要静态资源的请求经过Spring MVC框架的大门,如果不做额外的配置,就必然会跟拦截器扯上关系。
Xml配置方式:请点击这里
解决方案1:
静态资源统一交由Servlet容器直接处理
参考代码:
使用该接口WebApplicationInitializer可以实现web.xml配置文件的功能。
public class WebXml implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
//注册Spring MVC配置类来创建Spring MVC容器
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//SpringMvcConfig.class它是Spring Mvc的配置类,需要自行编写
ctx.register(SpringMvcConfig.class);
ctx.setServletContext(servletContext);
//添加default servlet映射路径,将静态资源的请求直接由Servlet容器处理
ServletRegistration defaultServlt = servletContext.getServletRegistration("default");
defaultServlt.addMapping("*.js", "*.css", "*.jpg","*.ico");
//配置Spring MVC入口点,注册DispatcherServlet
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
}
}
结论:
加上该配置,即可解决静态资源请求失败的问题,此刻与Spring MVC完全没有关系,所以配置Spring MVC拦截器时,不用考虑对静态资源的处理。
解决方案2:
静态资源统一交由Spring MVC框架间接处理,再转交给Servlet容器处理
源码参考:
DefaultServletHttpRequestHandler处理器所在的映射器里并没有去获取我们在配置类中配置的拦截器,所以我们配置的拦截器对这个处理器并不生效,那么拦截器就可以不用特意对静态资源的路径进行排除操作。
代码参考:
@EnableWebMvc
@ComponentScan(basePackages = "com.xxx.controller")
public class SpringMvcConfig implements WebMvcConfigurer {
//配置默认静态资源处理器
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable("default");
}
//配置Spring MVC拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
MyInterceptor myInterceptor = new MyInterceptor();
registry.addInterceptor(myInterceptor).addPathPatterns("/**");
}
}
总结:如果采用这种方式处理静态资源,即使拦截器不排除静态资源的请求,也不会拦截。
解决方案3:
静态资源统一交由Spring MVC框架直接处理
请查看截图中源码的差异性:
源码:Spring MVC5.0.0版本
从Spring MVC5.0.0版本中可以看出,ResourceHttpRequestHandler处理器的映射器并没有去获取配置类中的拦截器,所以,就算拦截器不排除静态资源的请求,也不会被拦截了。
结论:使用Spring MVC5.0.0版本或低版本开发的项目,配置拦截器的时候,即使不排除静态资源的路径,也不会对静态资源进行拦截,因为拦截器根本就没生效。
源码:Spring MVC5.0.1版本
从Spring MVC5.0.1版本配置信息中可以看出ResourceHttpRequestHandler处理器的映射器获取了所有的拦截器,包括配置类中的,如果配置拦截器不排除静态资源的话,将会拦截静态资源的请求。
结论:使用Spring MVC5.0.1版本或高版本开发的项目,如果拦截器不排除静态资源的请求,将会对静态资源进行拦截,因为静态资源处理器映射器已获取了配置类中的拦截器。
代码参考:
鉴于Spring MVC不同版本,建议采用统一在拦截器的配置中采用排除静态资源路径的方式,既适合高版本,也不影响低版本。
@EnableWebMvc
@ComponentScan(basePackages = "com.xxx.controller")
public class SpringMvcConfig implements WebMvcConfigurer {
//配置静态资源映射
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/jpg/**").addResourceLocations("/jpg/");
}
//配置Spring MVC拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
MyInterceptor myInterceptor = new MyInterceptor();
registry.addInterceptor(myInterceptor).addPathPatterns("/**")
.excludePathPatterns("/js/**", "/css/**", "/jpg/**");
}
}
总结:
1、如果采用第一种解决方案,拦截器不用做任何处理静态资源的操作。因为Spring MVC的DispatcherServlet没有匹配静态资源的请求。
2、如果采用第二种解决方案,拦截器也不用做任何处理静态资源的操作。因为配置类中的拦截器并没有生效。
2、如果采用第三种解决方案,鉴于Spring MVC不同版本,建议统一在拦截器的配置中采用排除静态资源的请求,既适合高版本,也不影响低版本。从而避免静态资源访问失败。
以上内容为自己的理解所获,如有误,欢迎留言指正,谢谢!
本文地址:https://blog.csdn.net/qq_39312911/article/details/112109383
上一篇: 教你自己在家卤鸡爪的做法大全