zoukankan      html  css  js  c++  java
  • 解决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("/**");
        }
    }
       
    

    总结:如果采用这种方式处理静态资源,即使拦截器不排除静态资源的请求,也不会拦截;但是请注意,如果采用Xml配置的方式,就必须要排除静态资源的请求,这是2者不同配置的区别,具体可以查看Xml配置的那篇文章,有详细说明。

    解决方案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不同版本,建议统一在拦截器的配置中采用排除静态资源的请求,既适合高版本,也不影响低版本。从而避免静态资源访问失败。

    以上内容为自己的理解所获,如有误,欢迎留言指正,谢谢!

  • 相关阅读:
    iOS:不同属性声明方式的解析
    iOS:图像和点击事件
    iOS:NAV+TABLE结合
    iOS:实现表格填充和选择操作
    iOS: 填充数据表格
    iOS:导航栏的工具条和导航条
    iOS:使用导航栏
    hello,world不使用ARC
    iOS代码实现:创建按钮,绑定按钮事件,读取控件值
    iOS版 hello,world版本2
  • 原文地址:https://www.cnblogs.com/coder-ahao/p/14225229.html
Copyright © 2011-2022 走看看