SpringBoot访问静态资源出现 404

项目场景

问题描述

编辑原因分析

解决方案

1. 将静态资源放在static 或 templates目录中

2. 继承WebMvcConfigurerAdapter  【已经过时】

3. 继承WebMvcConfiguratiWebonSupport 【推荐】

4. 实现WebMvcConfigurer接口 【推荐】

WebMvcConfiguratiWebonSupport 与 WebMvcConfigurer 区别

1. WebMvcProperties 和 ResourceProperties 失效

2. 类路径上的 HttpMessageConverter 失效


SpringBoot访问静态资源出现 404

项目场景

我们使用Springboot框架编写程序,里面使用到了静态资源,如下图所示的 backend目录 和 front目录,如果不进行配置,那么里面的静态文件将无法访问,会报 404的错误 

springboot 不拦截静态资源 springboot 静态资源请求被拦截_springboot 不拦截静态资源

问题描述

我们访问的时候,会出现如下问题

springboot 不拦截静态资源 springboot 静态资源请求被拦截_java_02

原因分析

在SpringBoot中集成了Tomcat,我们是不需要配置tomcat的,但是其设置了默认值,在不做任何配置的情况下,只能访问名为 static目录 或 templates目录下的静态资源!

所以我们可以简单粗暴的新建一个目录static,再将上述的两个目录移动至static下即可!

springboot 不拦截静态资源 springboot 静态资源请求被拦截_springboot 不拦截静态资源_03

如下所示:

springboot 不拦截静态资源 springboot 静态资源请求被拦截_WebMVCConfig_04

但是这样终究是治标不治本

解决方案

1. 将静态资源放在static 或 templates目录中

见上方,但是不推荐!

2. 继承WebMvcConfigurerAdapter  【已经过时】

产生诸多情况无法访问,配置麻烦,spring2.0以后不再建议使用

3. 继承WebMvcConfiguratiWebonSupport 【推荐】

springboot 不拦截静态资源 springboot 静态资源请求被拦截_springboot 不拦截静态资源_05

在config包下新建一个类WebMVCConfig,让其继承WebMvcConfiguratiWebonSupport

@Configuration
public class WebMVCConfig extends WebMvcConfigurationSupport {
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/front/**")
                .addResourceLocations("classpath:/front/");
        registry.addResourceHandler("/backend/**")
                .addResourceLocations("classpath:/backend/");
    }
}

4. 实现WebMvcConfigurer接口 【推荐】

与第三个方法类似,但是都是推荐的!!!

@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/backend/**")
                .addResourceLocations("classpath:/backend/");
        registry.addResourceHandler("/front/**")
                .addResourceLocations("classpath:/front/");
    }
}

WebMvcConfiguratiWebonSupport 与 WebMvcConfigurer 区别

在Spring Boot 2.0后用自己的的配置类继承WebMvcConfigurerAdapter时,idea会提示这个类已经过时了。 

所以我们在解决这个问题的时候,一般是使用:

  • 实现WebMvcConfigurer  
  • 继承WebMvcConfigurationSupport

但是继承WebMvcConfigurationSupport时发现会造成一些问题

我们可以先看看 WebMvcAutoConfiguration 类

springboot 不拦截静态资源 springboot 静态资源请求被拦截_spring_06

注意一下这个注解 @ConditionalOnMissingBean

SpringBoot做了这个限制,只有当WebMvcConfigurationSupport类不存在的时候才会生效WebMvc自动化配置,WebMvc自动配置类中不仅定义了classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/等路径的映射,还定义了配置文件spring.mvc开头的配置信息等。

1. WebMvcProperties 和 ResourceProperties 失效

因为两个配置类中的属性都在 WebMvcAutoConfiguration 中使用。当WebMvc自动配置失效(WebMvcAutoConfiguration自动化配置)时,会导致无法视图解析器无法解析并返回到对应的视图。

2. 类路径上的 HttpMessageConverter 失效

如:StringHttpMessageConverterConfiguration、MappingJackson2HttpMessageConverter ,因为 HttpMessageConverters 中持有着所有HttpMessageConverter的实例, 在WebMvcAutoConfigurationAdapter 中会注入 HttpMessageConverters ,因此当WebMvcAutoConfigurationAdapter 不加载时,则会失效,间接的造成spring.http.encoding.charset 与 spring.jackson.date-format 假象的失效。