Spring Boot 不僅擅長構建 REST API,對傳統服務端渲染 Web 應用同樣支援完善。本文系統講解靜態資源映射、主流模板引擎整合、視圖解析機制及 JSP 遷移建議。
classpath:/META-INF/resources/ classpath:/resources/ classpath:/static/ classpath:/public/
src/main/resources/static/ ├── css/style.css ├── js/app.js └── images/logo.png
啟動後直接訪問:https://localhost:8080/css/style.css、/js/app.js、/images/logo.png
spring:
web:
resources:
static-locations: classpath:/static/,classpath:/custom-static/
cache:
period: 3600
chain:
compressed: true
cache: true
| 引擎 | 語法風格 | Spring Boot 支援 | 適用場景 | 學習曲線 |
|---|---|---|---|---|
| Thymeleaf | 屬性式 (HTML 友好) | ⭐⭐⭐⭐⭐ 官方推薦 | 服務端渲染、郵件模板、前後端協作 | 低 |
| FreeMarker | 指令式 (類 JSP) | ⭐⭐⭐⭐ | 複雜報表、代碼生成、舊項目遷移 | 中 |
| Velocity | 指令式 (輕量) | ⭐⭐ (Spring Boot 2.3+ 移除自動配置) | 簡單模板、歷史項目 | 低 |
| Mustache | 無邏輯 (Logic-less) | ⭐⭐⭐ | 前後端分離共用模板、簡單頁面 | 極低 |
| Groovy Templates | Groovy DSL | ⭐⭐ | Groovy 技術棧項目 | 中 |
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
spring:
thymeleaf:
prefix: classpath:/templates/
suffix: .html
mode: HTML
encoding: UTF-8
cache: false # 開發關閉緩存
servlet:
content-type: text/html
模板文件 (templates/index.html)
<!DOCTYPE html> <html xmlns:th="https://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title th:text="${siteName} + ' - 首頁'">站點名稱</title> <link rel="stylesheet" th:href="@{/css/style.css}"> </head> <body> <h1 th:text="${siteName}">站點名稱</h1> <table> <thead> <tr><th>ID</th><th>用戶名</th><th>郵箱</th><th>狀態</th></tr> </thead> <tbody> <tr th:each="user : ${users}"> <td th:text="${user.id}">1</td> <td th:text="${user.username}">用戶名</td> <td th:text="${user.email}">郵箱</td> <td> <span th:switch="${user.status}"> <span th:case="'ENABLED'" class="badge success">啟用</span> <span th:case="'DISABLED'" class="badge warning">禁用</span> <span th:case="*" class="badge danger">未知</span> </span> </td> </tr> </tbody> </table> <script th:src="@{/js/app.js}"></script> </body> </html>Thymeleaf 核心語法速查
| 語法 | 用途 | 示例 |
|---|---|---|
| th:text | 設置文本內容 | <span th:text="${name}"></span> |
| th:utext | 設置非轉義 HTML | <div th:utext="${htmlContent}"></div> |
| th:each | 迴圈遍歷 | <li th:each="item : ${list}"></li> |
| th:if / th:unless | 條件渲染 | <div th:if="${user.loggedIn}"></div> |
| th:switch / th:case | 多條件分支 | 見上方表格狀態欄 |
| th:href / th:src | URL 解析 (支援 @{}) | <a th:href="@{/user/{id}(id=${user.id})}"> |
| th:object / th:field | 表單綁定 | <form th:object="${user}"><input th:field="*{name}"> |
| th:fragment / th:insert / th:replace | 模板片段復用 | <div th:insert="fragments/header :: header"> |
| #dates, #numbers, #strings | 工具對象格式化 | ${#dates.format(user.createdAt, 'yyyy-MM-dd')} |
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
spring:
freemarker:
template-loader-path: classpath:/templates/
suffix: .ftl
charset: UTF-8
settings:
number_format: '0.##'
datetime_format: 'yyyy-MM-dd HH:mm:ss'
classic_compatible: true
<#list users as user>
<tr>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.email}</td>
</tr>
</#list>
1. @RestController / @ResponseBody → HttpMessageConverter (JSON/XML) → 直接返回 2. 返回 View 名稱 (String) → ViewResolver 鏈: ├── ThymeleafViewResolver (spring.thymeleaf.enabled=true) ├── FreeMarkerViewResolver (spring.freemarker.enabled=true) ├── MustacheViewResolver ├── GroovyMarkupViewResolver └── InternalResourceViewResolver (JSP, 需額外配置) 3. 返回 ModelAndView / View 對象 → 直接渲染
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
</dependencies>
spring:
mvc:
view:
prefix: /WEB-INF/jsp/
suffix: .jsp
現代架構多採用:Spring Boot (REST API) + Vue/React/Angular (SPA)
/api/** 接口,靜態資源由 Nginx/CDN 服務Spring Boot 的視圖層設計體現了「有選擇、有預設、易擴展」。Thymeleaf 作為官方首推,以 HTML 原生語法、自然模板特性、完美 Spring 整合成為服務端渲染首選。理解視圖解析鏈優先級,合理規劃前後端分離邊界,才能發揮 Spring Boot Web 開發最大效能。