静态资源与 Thymeleaf
约 1105 字大约 4 分钟
布欧-Lewyon
2026-05-16
首页 › Spring Boot › Web 与 REST › 静态资源与 Thymeleaf
Spring Boot 内置了对静态资源和模板引擎的支持。在前后端分离成为主流的今天,Thymeleaf 使用场景减少,但内建容器的静态资源映射仍是基础能力。
静态资源映射
Spring Boot 默认从以下路径提供静态资源(优先级由高到低):
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/ ← 最常用
classpath:/public/src/main/resources/static/
├── index.html → http://localhost:8080/index.html
├── css/style.css → http://localhost:8080/css/style.css
├── js/app.js → http://localhost:8080/js/app.js
└── images/logo.png → http://localhost:8080/images/logo.png自定义静态资源路径
spring:
web:
resources:
static-locations: classpath:/static/,file:/data/static/
cache:
period: 3600 # 浏览器缓存 1 小时
cache-control: max-age=3600
add-mappings: true # 是否启用资源映射(默认 true)ResourceHandler 自定义
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 映射外部路径到 URL
registry.addResourceHandler("/uploads/**")
.addResourceLocations("file:/data/uploads/")
.setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS));
// Favicon 自定义
registry.addResourceHandler("/favicon.ico")
.addResourceLocations("classpath:/static/favicon.ico");
}
}Thymeleaf 模板引擎(简述)
在前后端未分离的场景中,Thymeleaf 是 Spring Boot 官方推荐的模板引擎,通过在 HTML 标签中添加 th:* 属性实现服务端渲染。
起步依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>模板文件放在 src/main/resources/templates/:
<!-- src/main/resources/templates/user.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>用户信息</title>
</head>
<body>
<h1 th:text="${user.userName}">默认名称</h1>
<p>年龄: <span th:text="${user.age}">0</span></p>
<ul>
<li th:each="order : ${user.orders}"
th:text="${order.orderNo}">订单号</li>
</ul>
</body>
</html>@Controller // 注意是 @Controller 不是 @RestController
@RequestMapping("/page")
public class UserPageController {
@GetMapping("/users/{id}")
public String userPage(@PathVariable Long id, Model model) {
model.addAttribute("user", userService.findById(id));
return "user"; // 对应 templates/user.html
}
}Thymeleaf vs 前后端分离
| 对比维度 | Thymeleaf(SSR) | 前后端分离(SPA) |
|---|---|---|
| 首次加载速度 | 快(服务器直出 HTML) | 慢(加载 JS + API 请求) |
| SEO | 友好(搜索引擎识别 HTML) | 差(需 SSR 预渲染) |
| 前后端耦合 | 高(模板中混业务逻辑) | 低(API 契约独立) |
| 后端改动范围 | 可能影响页面 | API 不变则前端不受影响 |
| 适用场景 | 管理后台、SEO 关键页面 | 高交互 App、多端复用 |
生产意识:前后端分离是 2026 年的主流实践。Thymeleaf 适合以下场景:①管理后台(交互简单,开发快);②需要 SEO 的页面(如官网、博客);③遗留系统的渐进改造过渡期。新项目建议默认采用前后端分离架构。
源码与架构:ResourceHandlerRegistry 注册链
WebMvcAutoConfiguration
│
└── addResourceHandlers(registry)
├── 注册默认资源映射(classpath:/META-INF/resources/ 等 4 个位置)
│ └── ResourceHttpRequestHandler
│ └── 根据 ResourceResolver 链解析资源位置
│ ├── PathResourceResolver(默认)
│ ├── GzipResourceResolver(.gz 优先)
│ └── EncodedResourceResolver(br/gzip 编码协商)
│
├── 注册 WebJars 映射(/webjars/** → classpath:/META-INF/resources/webjars/)
│
└── 应用自定义 ResourceHandlerRegistration
└── 优先级高于默认映射(后注册的优先级更高)Spring Boot 自动注册 ResourceHttpRequestHandler,每个请求先经过 ResourceResolver 链匹配。PathResourceResolver 是默认解析器,从 ResourceLocation 列表中查找文件。如果开启 GzipResourceResolver,会优先返回同名的 .gz 文件。
生产意识:
classpath:/static/中的文件在打包后位于 JAR 内部,无法直接通过文件系统修改——要更新静态资源需要重新打包。需要频繁更新的静态资源(如上传的图片、配置文件)应映射到外部路径(file:/data/static/)。spring.web.resources.cache.period设置的是响应头Cache-Control: max-age=3600——如果使用 CDN 分发静态资源,CDN 的缓存策略需要与此配合,否则浏览器侧缓存与 CDN 侧缓存不一致。
小结
- 静态资源默认从
classpath:/static/等 4 个位置映射,可通过ResourceHandler自定义外部路径。 - Thymeleaf 适合管理后台和 SEO 场景,新项目推荐前后端分离。
- 自定义静态资源路径使用
addResourceLocations("file:/path/")。 - 易错:
@Controller返回字符串时找的是templates/下的模板文件,不要和@RestController混淆。Thymeleaf 模板改完后需要重启应用(生产环境配置 spring.thymeleaf.cache=true 防止性能下降,开发阶段配 false 实现热重载)。静态资源 URL 末尾不带/可能造成相对路径解析错误——浏览器会拼接最后一个/之前的路径。外部静态资源路径需要确保应用有读取权限,容器化时通过卷挂载。 - 思考任务:创建一个静态首页
index.html放在static/下,启动应用后访问确认;配置WebMvcConfigurer.addResourceHandlers将外部目录映射为/uploads/**。
上一节:文件上传
下一节:测试
