Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
Thymeleaf
1.理解:
(1)Thymeleaf是一款Java模板引擎,類似於JSP,Freemarker,能夠處理html,xml,javaScript,Css甚至純文字;
(2)自然模板,原型即頁面
(3)語法優雅易懂,OGNL,SpringEL
(4)使用web標準,支援HTML5
2.Thymeleaf標準方言
(1)識別:
(2)方言內容:
(3)語法:
變量表達式:${........},用於儲存變數,例name
訊息表示式:#{.......},也被稱之為文字外部化,國際化後i18n,例city相當於key
選擇表示式:*{........},與變量表達式的區別:他們是在當前選擇的物件而不是整個上下文變數對映上執行
連結表示式:@{........},連結表示式可以是相對的,在這種情況下,應用程式上下文將不會作為URL的字首,
也可以是伺服器相對(同樣,沒有應用程式上下文字首),
和協議相對(就像絕對URL,但瀏覽器使用在顯示的頁面中使用的相同的HTTP和Https協議),
當然,Link表示式可以是絕對的,
分段表示式:th:insert或th:replace
(4)字面量(文字):
文字:
數字(可以執行計算等):
布林:
Null:
算術操作:+,-,*,/,%(加減乘除取餘)
比較:<,>,<=,>=(lt,gt,le,ge)
等價:==,!=(eq,ne)
條件運算子:
無操作:_
(5)設定屬性值:
設定任意屬性值:th:attr
設定值到指定的屬性:
固定值布林屬性:
(6)迭代器:
基本迭代器:th:each
狀態變數:index,count,size,current,even/odd,first/last
(7)條件語句:
th:if,th:unless
Switch:
3.Thymeleaf與Spring boot整合
(1)模板佈局(我們在開發中可以看到頁面中有許多的公用片段)
方式一:定義和引用片段:th:insert
方式二:不使用th:fragment
th:insert,th:replace,th:include三者的區別
●th:insert它將簡單的插入指定的片段作為正文的主標籤
●th:replace用指定實際片段來替換其他主標籤
●th:include類似於insert,不常用,瞭解即可
(2)屬性優先順序
(3)註釋:
解析器級別註釋(解析快中內容執行時會被刪除)
(4)內聯表示式:
[[.....]]或[(.....)]分別對應於th;text和th:utext
禁用內聯:
有時需要禁用這種機制,比如,想輸出[[.......]]或[(...)]文字內容
javaScript內聯與Css均可以進行內聯
(5)表示式的基本物件
基本物件:
#ctx:上下文物件
#locale:直接訪問java.util.Locale相關聯的當前的請求
Request/session等屬性
Param:用於檢索請求引數
Session:用於檢索Session屬性
Application:用於檢索Application/servlet上下文屬性
Web上下文物件:#Request,#Session,#ServletContext
(6)Thymeleaf與Spring boot整合
我們建立第一個Spring boot+Thymeleaf+mevan專案,測試專案是否正常執行:
專案建立成功後,我們匯入IDE中,開啟專案,我們編寫一個helloController,專案結構如下:
測試專案是否能正常執行,我們新增Controller,讓它輸出一個字串,程式碼如下:
package com.dhtt.spring.boot.blog.thymeleaf.action.web;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class helloController {
@GetMapping("/hello")
public String sayHello(HttpServletRequest request) {
String say="START TEST THYMELEAF,SAY HELLO WORD!!";
System.out.println("say: "+say);
return say;
}
}
接下來啟動的專案,專案正常啟動後,我們在瀏覽器,訪問頁面地址,觀察結果,:
由此可以看出我們的專案正常執行,可以進入下一步的開發
4.實戰Spring boot+thymeleaf,我們來實現一個簡單的使用者管理
(1)修改application.properties配置檔案
spring.thymeleaf.encoding=UTF-8
#熱部署靜態檔案,不需要快取,實時觀察檔案修改效果
spring.thymeleaf.cache=false
#使用html5標準
spring.thymeleaf.mode=HTML5
(2)API設計:
·GET /users:返回用於展示使用者列表的list.html頁面
·GET /users/{id}:返回用於展示使用者的view.html頁面,根據id獲取的
·GET /users/form:返回用於新增或者修改使用者的form.html頁面
·POST /users:新增或者修改使用者,成功後重定向到list.html頁面
·GET /users/delete/{id}:根據id刪除相應的使用者,成功後重定向到list.html頁面
·GET /users/modify/{id}:根據id獲取相應的使用者資料,並返回form頁面來進行修改
(3)後臺編碼:
首先展示專案後臺結構:
User實體(主要程式碼):
package com.dhtt.spring.boot.blog.thymeleaf.action.entity;
/**
* user實體
*
* @author QT
*/
public class User {
private Long id; // 使用者的唯一標識
private String name; // 使用者名稱
private String email; // 使用者郵箱
public User() {
super();
}
public User(Long id, String name, String email) {
super();
this.id = id;
this.name = name;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
定義資源庫(interface UserRepository)包含方法如下:
package com.dhtt.spring.boot.blog.thymeleaf.action.repository;
/**
* User Repository介面
* @author QT
*
*/
import java.util.List;
import com.dhtt.spring.boot.blog.thymeleaf.action.entity.User;
public interface UserRepository {
/**
* 修改或增加使用者
*
* @param user
* @return
*/
public User saveOrUpdateUser(User user);
/**
* 根據Id刪除使用者
*
* @param id
*/
public void deleteUser(Long id);
/**
* 根據Id查詢使用者
*
* @param id
* @return
*/
public User getUserById(Long id);
/**
* 獲取使用者列表
*
* @return
*/
public List<User> listUser();
}
實現資源庫,即實現增刪改查的操作
package com.dhtt.spring.boot.blog.thymeleaf.action.repository.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.stereotype.Repository;
import com.dhtt.spring.boot.blog.thymeleaf.action.entity.User;
import com.dhtt.spring.boot.blog.thymeleaf.action.repository.UserRepository;
@Repository
public class UserRepositoryImpl implements UserRepository {
// 用於計數的計數器,為了設定唯一Id
private static AtomicLong counter = new AtomicLong();
private final ConcurrentMap<Long, User> userMap = new ConcurrentHashMap<Long, User>();
@Override
public User saveOrUpdateUser(User user) {
Long id = user.getId();
if (id == null) { // 新增使用者
id = counter.incrementAndGet();
user.setId(id);
}
this.userMap.put(id, user);
return user;
}
@Override
public void deleteUser(Long id) {
this.userMap.remove(id);
}
@Override
public User getUserById(Long id) {
return this.userMap.get(id);
}
@Override
public List<User> listUser() {
return new ArrayList<User>( this.userMap.values());
}
}
接下來編寫Controller層,實現與前臺的資料互動
package com.dhtt.spring.boot.blog.thymeleaf.action.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.dhtt.spring.boot.blog.thymeleaf.action.entity.User;
import com.dhtt.spring.boot.blog.thymeleaf.action.repository.UserRepository;
@RestController
@RequestMapping("/users")
public class userController {
@Autowired
private UserRepository userRepository;
/**
* 查詢所有使用者
*
* @param model
* @return
*/
@GetMapping
public ModelAndView list(Model model) {
model.addAttribute("userList", userRepository.listUser());
model.addAttribute("title", "使用者管理");
return new ModelAndView("users/list", "userModel", model);
}
/**
* 根據Id查詢使用者
*
* @param id
* @param model
* @return
*/
@GetMapping("{id}")
public ModelAndView view(@PathVariable("id") Long id, Model model) {
User user = userRepository.getUserById(id);
model.addAttribute("user", user);
model.addAttribute("title", "使用者查詢");
return new ModelAndView("users/view", "userModel", model);
}
/**
* 建立使用者
*
* @param id
* @param model
* @return
*/
@GetMapping("/form")
public ModelAndView createForm(Model model) {
model.addAttribute("user", new User());
model.addAttribute("title", "建立使用者");
return new ModelAndView("users/form", "userModel", model);
}
/**
* 新增或修改使用者
*
* @param user
* @return
*/
@PostMapping
public ModelAndView saveOrUpdateUser(User user) {
user = userRepository.saveOrUpdateUser(user);
return new ModelAndView("redirect:/users", "userModel", user);
}
/**
* 獲取刪除使用者
*
* @param id
* @return
*/
@GetMapping("/delete/{id}")
public ModelAndView deleteUser(@PathVariable("id") Long id) {
userRepository.deleteUser(id);
return new ModelAndView("redirect:/users"); // 重定向到list頁面
}
/**
* 獲取修改使用者介面
*
* @param id
* @param model
* @return
*/
@GetMapping("/modify/{id}")
public ModelAndView modify(@PathVariable("id") Long id, Model model) {
User user = userRepository.getUserById(id);
model.addAttribute("user", user);
model.addAttribute("title", "修改使用者");
return new ModelAndView("users/form", "userModel", model);
}
}
後臺寫完以後,我們對前臺進行編寫:
(4)前臺編碼:
首先編寫頁面的頭和尾,即為公共的html
展示前臺專案結構:
公共程式碼片段—header.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Thymeleaf 使用者管理</title>
</head>
<body>
<div th:fragment="header">
<h1>Thymeleaf in action</h1>
<a href="/users" th:href="@{~/users}">首頁</a>
</div>
</body>
</html>
公共程式碼片段—footer.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Thymeleaf 使用者管理</title>
</head>
<body>
<div th:fragment="footer">
<a href="http://blog.51cto.com/13501268">Welcome to http://blog.51cto.com/13501268</a>
</div>
</body>
</html>
公共頁面編寫完畢,進行功能頁面編寫:
功能頁面—list.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Thymeleaf 使用者管理</title>
</head>
<body>
<div th:replace="~{fragments/header :: header}"></div>
<h3 th:text="${userModel.title}"></h3>
<div>
<a href="/users/form.html" th:href="@{/users/form}">建立使用者</a>
</div>
<table border="1">
<thead>
<tr>
<td>ID</td>
<td>Email</td>
<td>Name</td>
</tr>
</thead>
<tbody>
<tr th:if="${userModel.userList.size()} eq 0">
<td colspan="3">沒有使用者資訊!!</td>
</tr>
<tr th:each="user : ${userModel.userList}">
<td th:text="${user.id}"></td>
<td th:text="${user.email}"></td>
<td><a th:href="@{'/users/'+${user.id}}" th:text="${user.name}"></a></td>
</tr>
</tbody>
</table>
<div th:replace="~{fragments/footer :: footer}"></div>
</body>
</html>
功能頁面—form.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Thymeleaf 使用者管理</title>
</head>
<body>
<div th:replace="~{fragments/header :: header}"></div>
<h3 th:text="${userModel.title}"></h3>
<form action="/users" th:action="@{/users}" method="post" th:object="${userModel.user}">
<input type="hidden" name="id" th:value="${userModel.user.id}">
名稱:<br>
<input type="text" name="name" th:value="*{name}"><br>
郵箱:<br>
<input type="text" name="email" th:value="*{email}"><br>
<input type="submit" value="提交">
</form>
<div th:replace="~{fragments/footer :: footer}"></div>
</body>
</html>
功能頁面—view.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Thymeleaf 使用者管理</title>
</head>
<body>
<div th:replace="~{fragments/header :: header}"></div>
<h3 th:text="${userModel.title}"></h3>
<div>
<p><strong>ID:</strong><span th:text="${userModel.user.id}"></span></p>
<p><strong>NAME:</strong><span th:text="${userModel.user.name}"></span></p>
<p><strong>EMAIL:</strong><span th:text="${userModel.user.email}"></span></p>
</div>
<div>
<a th:href="@{'/users/delete/'+${userModel.user.id}}">刪除</a>
<a th:href="@{'/users/modify/'+${userModel.user.id}}">修改</a>
</div>
<div th:replace="~{fragments/footer :: footer}"></div>
</body>
</html>
我們啟動專案進行功能測試,截圖展示:
點選建立使用者:
點選提交,新增成功重定向到list.html頁面:
點選名稱,展示詳細資訊:
點選修改,跳轉到form.html頁面,並填寫修改資訊:
點選提交重定向到list.html,頁面,可以發現資訊已經修改成功:
接下來檢視詳細資訊
點選刪除,重定向到list.html頁面:
觀察結果,我們發現數據信息刪除成功,專案展示完畢,thymeleaf+spring+mevan學習完畢