Thymeleaf
是Spring Boot 推薦使用的前端模板引擎,它除了可以完全取代JSP 外,還有以下三個優點。
變量表達式即OGNL 表達式或Spring EL 表達式,傳入控制器設定的name 值。
<span th:text="${name}"></span>
選擇表達式跟變量表達式很像,不過它是用一個預先選擇的對象來取代上下文變數容器執行。
<div th:Object="${book}">
...
<span>[[*{title}]]</span>
...
</div>
文字國際化表達式允許我們從一個外部檔案獲取文字資訊,通過鍵值來引用文字訊息,在Spring 中,可自動與Spring 的MessageSource 機制集成。
<table>
...
<th th:text="#{header.address.city}">...</th>
...
</table>
若希望表達式由上下文變量的值決定,或希望將變量指定為參數,則可以在表達式中使用變量表達式。
#{${config.adminWelcomeKey}(${session.user.name})}
URL 表達式指的是把一個有用的上下文或回話資訊新增到URL,這個過程經常被叫做URL 重寫。
<link rel="stylesheet" th:href="@{/css/reset.css}">
可以設定參數
<a th:href="@{/order/details(id=${orderId})}"></a>
其結果為
<a href="/order/details?id=1">...</a>
也可以為相對路徑,但應用程式上下文不會被加到URL 前面
<a th:href="@{../documents/report}"></a>
還可以是與伺服器的相對路徑,同樣應用程式上下文不會被加到URL 前面
<a th:href="@{~/contents/main}"></a>
當然,也可以設定為絕對路徑
<a th:href="@{http://www.mycompany.com/main}">...</a>
因為標籤的使用方法大多為th:
加上HTML 標籤後再交由表達式賦值或判斷,因次這邊只列出比較特殊的使用範例。
th:object
: 用於接收後台傳過來的物件。th:field
: 用於綁定後台物件和表單資料,可同時設定id 和name 為後台物件屬性,且value 為該屬性值。<form th:object="${user}">
<input th:field="*{account}"/>
<input th:field="*{password}"/>
</form>
HTML 解析結果如下
<form>
<input id="account" name="account" value="account"/>
<input id="password" name="password" value="password"/>
</form>
th:fragment
: 標記重複程式區塊。
假設有一區塊設定為block.html,其內容為
<div th:fragment="block">
<h1>Thymeleaf Block</h1>
</div>
th:insert
: 區塊插入所屬標籤中。
<section th:insert="block :: block"></section>
效果為
<section>
<div>
<h1>Thymeleaf Block</h1>
</div>
</section>
th:replace
: 區塊取代所屬標籤。
<section th:replace="block :: block"></section>
效果為
<div>
<h1>Thymeleaf Block</h1>
</div>
th:include
: 區塊內容插入所屬標籤中(3.0 開始不建議使用)。
<section th:include="block :: block"></section>
效果為
<section>
<h1>Thymeleaf Block</h1>
</section>
th:each
: 遍歷整個List 或Array 物件。
<select th:each="item : ${list}">
<option th:value="${item.value}">[[${item.name}]]</option>
</select>
th:if
: 條件成立時顯示。th:unless
: 條件不成立時顯示。<div>
<span th:if="${user == null}">User 不存在</span>
<span th:unless="${user == null}">User 存在</span>
</div>
當User 存在時,效果為
<div>
<span>User 存在</span>
</div>
Switch 判斷
th:switch
: 多選擇判斷,指定case 判斷變數。th:case
: 判斷switch 指定變數為何。<div th:switch="${user.role}">
<span th:case="admin">管理員</span>
<span th:case="vip">VIP 會員</span>
<span th:case="*">普通會員</span>
</div>
當User 的role 不為admin 或vip 時,效果為
<div>
<span>普通會員</span>
</div>
<!-- thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
# 表示是否啟用Thymeleaf 的快取
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.resources.static-locations=classpath:/static/
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="css">
<link rel="stylesheet" th:href="@{/css/reset.css}">
<link rel="stylesheet" th:href="@{/css/main.css}">
</head>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="js">
<script th:src="@{/js/lib/jquery-3.4.1.js}"></script>
<script th:src="@{/js/validation.js}"></script>
</head>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>會員登入</title>
<head th:insert="load/css :: css"></head>
<head th:insert="load/js :: js"></head>
<link rel="stylesheet" th:href="@{/css/login.css}">
</head>
<body>
<main>
<h1>會員登入</h1>
<form id=loginForm method="POST" th:action="@{/login}" th:Object="${memberAccount}" enctype="multipart/form-data" autocomplete="off">
<section class="form-input">
<label>帳號/Email</label>
<div class="input-area">
<div class="input-img"><img th:src="@{/images/person.png}"></div>
<input type="text" th:field="*{username}" placeholder="請輸入您的Email"/>
</div>
</section>
<section class="form-input">
<label>密碼</label>
<div class="input-area">
<div class="input-img"><img th:src="@{/images/lock.png}"></div>
<input type="password" th:field="*{password}" maxlength="16" placeholder="請輸入您的密碼"/>
</div>
</section>
<button>登入</button>
<span>還不是會員嗎?<a th:href="@{/register}">立即加入</a></span>
</form>
</main>
<script th:src="@{/js/login.js}"></script>
</body>
</html>
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.example.demo.entity.MemberAccount;
import com.example.demo.vo.MemberAccountVO;
@Controller
public class MemberAccountController {
@RequestMapping(value = {"/", "/login"}, method = RequestMethod.GET)
public String login(@ModelAttribute MemberAccount memberAccount) {
return "login";
}
}
新增Thymeleaf 依賴及其配置
新增所需HTML 檔案及相關靜態資源與功能配置