本人在项目中遇到关于配置拦截器后静态资源访问不到的问题,困扰了我好久,现在分享出来,和大家一起学习。
SpringBoot版本:2.2.0
SpringBoot 1.X 版本和 SpringBoot 2.X 版本在静态资源访问上有一些区别,如果直接从 1.X 升级到 2.X 肯定是有问题的。要作出相应的调整。
首先自定义拦截器,具体的做法是:继承HandlerInterceptor,重写里面的方法preHandle(),postHandle(),afterCompletion(),需求不同,在每个方法中实现自己的逻辑,在此重点重写 preHandle()。在此需要特别注意的是:preHandle方法是在return true的情况下才能向下执行,否则会拦截,如果再次不写任何逻辑代码,只想测试,一定请注意。

@Component
public class MyIntercept implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws IOException {
        Student stu = (Student) request.getSession().getAttribute("studentSession");
        if(null == stu){
            response.sendRedirect(request.getContextPath()+"/");
            return false;
        }
        return true;//只有返回true才会向下执行,返回false取消当前请求。
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {

    }
}

Springboot2.x访问静态资源的方式和Springboot1.x不同,1.x默认实在static文件夹下面,而2.x需要显示的说明,我们需要利用配置文件来实现。首先WebMvcConfigurerAdapter 已经过时,不建议使用。我们既可以继承WebMvcConfigurationSupport类,也可以实现WebMvcConfigurer 接口。继承WebMvcConfigurationSupport类时,这儿需要说明一下,WebMvc的自动配置都在WebMvcAutoConfiguration类中,请看源码:

@Configuration
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
    public static final String DEFAULT_PREFIX = "";
    public static final String DEFAULT_SUFFIX = "";
    private static final String[] SERVLET_LOCATIONS = new String[]{"/"};
 
    public WebMvcAutoConfiguration() {
    }
@Configuration
@ConditionalOnWebApplication(
    type = Type.SERVLET
)

仔细观察可以发现,类中有@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})这个注解,这个注解的意思是一旦在容器中检测到WebMvcConfigurationSupport这个类,WebMvcAutoConfiguration类中的配置就都不生效,只有在我们的的容器中没有这个组件的时候,自动配置类才会生效(唉。。。自己挖坑啊。。。)。所以一旦我们自己写的配置类继承了WebMvcConfigurationSupport,就相当于我们的容器中已经导入了WebMvcConfigurationSupport这个组件,所以默认配置都不会生效,都得自己在配置文件中配置。请看下面的配置:

@Configuration
public class MyWebConfig extends WebMvcConfigurationSupport {
    @Autowired
    private MyIntercept myIntercept;
    //静态资源配置
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").
                addResourceLocations("classpath:/resources/").
                addResourceLocations("classpath:/static/");
        super.addResourceHandlers(registry);
    }

    /**
     * 配置拦截器的不拦截的路径时,这个很重要。如果没配或者说配错的话都会有一个问题出现。
     * 就是重定向次数过多,导致网页无法响应。
     * @param registry
     */
    protected void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(new MyIntercept()).
                addPathPatterns("/**").excludePathPatterns("/","/login","/main");
        super.addInterceptors(registry);
    }

    protected void addViewControllers(ViewControllerRegistry registry){
        registry.addViewController("/").setViewName("login");
        super.addViewControllers(registry);
    }
}

当然,你还可以实现WebMvcConfigurer 这个接口,利用默认配置避免入坑。
将拦截器注入,在此类上面一定要注意加上@Configuration,才会在项目运行前扫描配置类信息。在此特别要注意的一点就是, addPathPatterns("/**")表是拦截所有,excludePathPatterns("/","/login","/main")表是这三个请求是开放的,在放开请求时,一定不要配置错或者不配置,负责就会导致无限重定向,陷入死循环,导致网页无法响应。