盘点那些静态资源404

399 阅读3分钟

image.png   在springboot开发过程中,有时候会有这样的需求。比如将前端的vue打包然后放到springboot项目的resources下。结果一顿操作猛如虎,结果游览器404。当然还有其他的静态资源场景,通过今天的学习,你会对这类问题处理起来更加得心应手。

1. springboot中默认的静态资源路径

先说结论,在springboot中,静态资源的访问路由一共有四个,分别是: classpath:/META-INF/resources/classpath:/resources/classpath:/static/classpath:/public/。在springboot项目中,classpath指的是src.main.java和src.main.resources路径以及第三方jar包的根路径,存放在这两个路径下的文件,都可以通过classpath作为相对路径来引用:

image.png

2.实践

上面讲了4个位置并说明了src.main.resources可以通过 classpath 作为相对路径引用。接下来创建如下四个目录,并在里面分别放四个txt文件,在里面随便写点内容即可,如下图所示。

image.png

接下来启动我们的项目,并在游览器上面访问以下地址:

会得到如下的展示:

image.png image.png image.png image.png

3.自定义路径

看到这里就会有小伙伴说,我TM就想放到src.main.resources目录下,不想再去建立那么多目录。更或者说,我直接在resources下建立一个img文件夹里面放点图片。因为这样会比在resources下面再去建立上面说的默认的四个路径更直观。

image.png 重启项目后,发现http://localhost:8080/meimei.jpg 会404,这是因为springboot并不能识别这个路径,需要你手动的去配置。我们新建一个WebConfig如下图所示:

image.png

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/img/");
    }
}

这个时候重启项目,再去访问:http://localhost:8080/meimei.jpg

image.png

但是此时你再去访问之前的会404:

这里为什么会404呢?因为添加了自定义的所以导致默认的不会生效吗? 答案是否定的,默认的路径依然会生效,只是由于我们自己添加的路径是/**是会匹配所有的请求。这就自然包括了 /1.txt /2.txt 或者 /xx/xxx/xxx 等路由。他们就会去我们自定义的classpath:/img/下面找这些资源。由于下面本来就没有所以,就是404啦。解决办法,我们可以给自定义的添加一个限定,比如匹配以 /img 开头的路径:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/img/**") // 重点在这里
                .addResourceLocations("classpath:/img/");
    }
}

接下来再去访问下面5个路径都可以正确访问到资源:

为什么默认的只有那四个路径

看到这里可能有人就有疑问了,为什么默认的路径是那四个。这个其实之前WebMvcConfigurer它的其中一个子类WebMvcAutoConfiguration找到答案。

image.png

这里调用了 this.resourceProperties.getStaticLocations(), 我们去看看getStaticLocations()方法:它是直接返回了staticLocations

image.png

而这个staticLocations是一个字符串数组,它默认初始化的代码如下:

image.png 如此真相大白!相信读到这里你以后遇到静态资源404的问题都会迎刃而解。