目录
- 一、引言
- 二、默认映射规则
- [2.1 四个默认目录](#2.1 四个默认目录)
- [2.2 验证访问](#2.2 验证访问)
- 三、动态资源与静态资源同名
- 四、定制静态资源映射
- [4.1 配置访问前缀](#4.1 配置访问前缀)
- [4.2 修改默认映射目录](#4.2 修改默认映射目录)
- [4.3 配置项的版本差异](#4.3 配置项的版本差异)
- 五、Webjars
- [六、欢迎页与 favicon](#六、欢迎页与 favicon)
- [6.1 欢迎页](#6.1 欢迎页)
- [6.2 favicon](#6.2 favicon)
- [6.3 映射前缀的副作用](#6.3 映射前缀的副作用)
- 七、总结
一、引言
SpringBoot 对静态资源的访问提供了固定的映射规则,只要按官方规则放置静态资源就可以直接访问。本文围绕这套规则展开:默认的四个映射目录、动态资源与静态资源同名时的优先级、如何定制访问前缀和映射目录、Webjars 访问,以及欢迎页和 favicon。
这套规则全部由自动配置类 WebMvcAutoConfiguration 定义,文中的每条规则在该类源码中都能找到对应实现。
二、默认映射规则
2.1 四个默认目录
根据官方文档,把静态资源放在类路径下的以下任一目录,即可直接访问:
/static/public/resources/META-INF/resources
2.2 验证访问
创建对应目录,分别放入一个 html 文件:
text
resources
├── META-INF
│ └── resources
│ └── a.html
├── public
│ └── b.html
├── resources
│ └── c.html
└── static
└── d.html
重启项目,按当前项目根路径/ + 静态资源名的规则访问:
text
http://localhost:8088/a.html
http://localhost:8088/b.html
http://localhost:8088/c.html
http://localhost:8088/d.html
经测试均可访问。
三、动态资源与静态资源同名
如果定义一个动态资源,同时存在一个同名映射路径的静态资源,最终访问到的是哪个?
定义一个映射路径为 a.html 的动态资源:
java
@RequestMapping("a.html")
public String hello(){
return "hello";
}
重启项目访问 http://localhost:8088/a.html,页面输出:
text
hello
访问到的是动态资源。
结论:请求进来,先找 Controller 看能不能处理;Controller 处理不了的请求,全部交给静态资源处理器;静态资源也找不到,响应 404。
四、定制静态资源映射
4.1 配置访问前缀
同名的静态资源和动态资源都要能访问时,可以给静态资源配置一个请求前缀:
yaml
spring:
mvc:
static-path-pattern: /hello/** # 配置访问静态资源的前缀
配置后,用之前的规则访问 http://localhost:8088/c.html,返回 Whitelabel Error Page(404),因为静态资源已经挂到了前缀之下。
加上前缀访问 http://localhost:8088/hello/c.html,正常返回页面内容。
4.2 修改默认映射目录
默认的四个映射目录也可以替换:
yaml
spring:
web:
resources:
static-locations: [classpath:/hello/] # 改变静态资源的默认映射目录
在类路径下创建 hello 目录并放入 e.html,重启后访问 http://localhost:8088/hello/e.html(此处的 /hello 前缀来自 4.1 的配置),页面正常返回。
注意这是替换而非追加:配置后原来的 static、public 等四个目录全部失效。
4.3 配置项的版本差异
static-locations 配置项的位置随版本变过一次:
- SpringBoot 2.4 之前:
spring.resources.static-locations - SpringBoot 2.4 及之后:
spring.web.resources.static-locations
2.4+ 项目里写旧 key 不会报错,但配置不生效。static-path-pattern 则一直在 spring.mvc 下,没有变化。
五、Webjars
SpringBoot 也支持对 Webjars 资源的访问。Webjars 就是把静态资源(jquery、bootstrap 等前端库)打成 jar 包,通过 Maven 管理。
需求:在 SpringBoot 项目里访问 jquery 库文件。
第一步,引入 jquery 依赖:
xml
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
引入后可以在项目依赖中看到 jar 包结构:
text
jquery-3.5.1.jar
└── META-INF
└── resources
└── webjars
└── jquery
└── 3.5.1
├── jquery.js
├── jquery.min.map
└── ...
第二步,重启项目,访问:
text
http://localhost:8088/webjars/jquery/3.5.1/jquery.js
可以看出原理:jar 包内的资源放在 /META-INF/resources 下,正是四个默认映射目录之一,所以天然可以被访问到。
六、欢迎页与 favicon
6.1 欢迎页
SpringBoot 支持将 index.html 放置在静态资源映射目录下,作为欢迎页:
text
static
├── d.html
├── favicon.ico
└── index.html
重启项目,直接访问 localhost:8088,首页内容正常显示。
按官方文档,SpringBoot 会先在静态资源目录中查找 index.html,找不到再查找名为 index 的模板,二者有其一即作为应用的欢迎页。
6.2 favicon
浏览器标签页的图标同样只需把 favicon.ico 放置在静态资源目录即可,重启后自动生效。
6.3 映射前缀的副作用
注意:如果配置了静态资源的映射前缀,首页 index.html 就访问不了了。
yaml
spring:
mvc:
static-path-pattern: /hello/** # 会导致首页 index.html 访问不了
favicon 同理------它本质也是一个静态资源,挂上前缀后浏览器按固定路径 /favicon.ico 请求不到它。原因要到 WebMvcAutoConfiguration 的欢迎页源码里找,本文不展开。
七、总结
- 静态资源默认映射四个类路径目录:
/static、/public、/resources、/META-INF/resources,访问规则是项目根路径 + 资源名; - 请求优先级:Controller → 静态资源处理器 → 404;
spring.mvc.static-path-pattern给静态资源加访问前缀,解决与动态资源同名冲突;static-locations替换(非追加)默认映射目录,2.4+ 版本配置 key 为spring.web.resources.static-locations;- Webjars 把前端库打成 jar 包,资源位于 jar 内的
/META-INF/resources/webjars/,故可按/webjars/**路径直接访问; index.html与favicon.ico放入静态资源目录即生效;配置映射前缀后二者失效,原因在WebMvcAutoConfiguration的源码实现中;- 以上全部规则由
WebMvcAutoConfiguration自动配置。