欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

三、解决Spring MVC拦截器导致静态资源访问失败(基于java注解配置)

程序员文章站 2023-11-08 12:28:40
前言对于这个问题,我们准备了以下三种解决方案:1、静态资源统一交由Servlet容器直接处理;2、静态资源统一交由Spring MVC框架间接处理,再转交给Servlet容器处理;3、静态资源统一交由Spring MVC框架直接处理;从这3种解决方案中,处理静态资源的方式可以分为Servlet容器处理和Spring MVC框架处理。在这里要说明的是,只要静态资源的请求经过Spring MVC框架的大门,如果不做额外的配置,就必然会跟拦截器扯上关系。解决方案1:静态资源统一交由Servlet容器...

前言

对于这个问题,我们准备了以下三种解决方案:
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拦截器导致静态资源访问失败(基于java注解配置)

结论:
加上该配置,即可解决静态资源请求失败的问题,此刻与Spring MVC完全没有关系,所以配置Spring MVC拦截器时,不用考虑对静态资源的处理。

解决方案2:

静态资源统一交由Spring MVC框架间接处理,再转交给Servlet容器处理

源码参考:
三、解决Spring MVC拦截器导致静态资源访问失败(基于java注解配置)
三、解决Spring MVC拦截器导致静态资源访问失败(基于java注解配置)
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 MVC拦截器导致静态资源访问失败(基于java注解配置)

从Spring MVC5.0.0版本中可以看出,ResourceHttpRequestHandler处理器的映射器并没有去获取配置类中的拦截器,所以,就算拦截器不排除静态资源的请求,也不会被拦截了。

结论:使用Spring MVC5.0.0版本或低版本开发的项目,配置拦截器的时候,即使不排除静态资源的路径,也不会对静态资源进行拦截,因为拦截器根本就没生效。

源码:Spring MVC5.0.1版本
三、解决Spring MVC拦截器导致静态资源访问失败(基于java注解配置)
三、解决Spring MVC拦截器导致静态资源访问失败(基于java注解配置)

从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