在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作为相对路径来引用:
2.实践
上面讲了4个位置并说明了src.main.resources可以通过 classpath 作为相对路径引用。接下来创建如下四个目录,并在里面分别放四个txt文件,在里面随便写点内容即可,如下图所示。
接下来启动我们的项目,并在游览器上面访问以下地址:
- http://localhost:8080/1.txt
- http://localhost:8080/2.txt
- http://localhost:8080/3.txt
- http://localhost:8080/4.txt
会得到如下的展示:
3.自定义路径
看到这里就会有小伙伴说,我TM就想放到src.main.resources目录下,不想再去建立那么多目录。更或者说,我直接在resources下建立一个img文件夹里面放点图片。因为这样会比在resources下面再去建立上面说的默认的四个路径更直观。
重启项目后,发现http://localhost:8080/meimei.jpg 会404,这是因为springboot并不能识别这个路径,需要你手动的去配置。我们新建一个
WebConfig如下图所示:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/img/");
}
}
这个时候重启项目,再去访问:http://localhost:8080/meimei.jpg
但是此时你再去访问之前的会404:
- http://localhost:8080/1.txt
- http://localhost:8080/2.txt
- http://localhost:8080/3.txt
- http://localhost:8080/4.txt
这里为什么会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个路径都可以正确访问到资源:
- http://localhost:8080/1.txt
- http://localhost:8080/2.txt
- http://localhost:8080/3.txt
- http://localhost:8080/4.txt
- http://localhost:8080/img/meimei.jpg
为什么默认的只有那四个路径
看到这里可能有人就有疑问了,为什么默认的路径是那四个。这个其实之前WebMvcConfigurer它的其中一个子类WebMvcAutoConfiguration找到答案。
这里调用了 this.resourceProperties.getStaticLocations(), 我们去看看getStaticLocations()方法:它是直接返回了staticLocations
而这个staticLocations是一个字符串数组,它默认初始化的代码如下:
如此真相大白!相信读到这里你以后遇到静态资源404的问题都会迎刃而解。