1. 程式人生 > >Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf

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)識別:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
(2)方言內容:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
(3)語法:
變量表達式:${........},用於儲存變數,例name
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
訊息表示式:#{.......},也被稱之為文字外部化,國際化後i18n,例city相當於key
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
選擇表示式:*{........},與變量表達式的區別:他們是在當前選擇的物件而不是整個上下文變數對映上執行
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf

連結表示式:@{........},連結表示式可以是相對的,在這種情況下,應用程式上下文將不會作為URL的字首,
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
也可以是伺服器相對(同樣,沒有應用程式上下文字首),
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
和協議相對(就像絕對URL,但瀏覽器使用在顯示的頁面中使用的相同的HTTP和Https協議),
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
當然,Link表示式可以是絕對的,
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
分段表示式:th:insert或th:replace
(4)字面量(文字):
文字:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
數字(可以執行計算等):
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
布林:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
Null:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
算術操作:+,-,*,/,%(加減乘除取餘)
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
比較:<,>,<=,>=(lt,gt,le,ge)
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
等價:==,!=(eq,ne)
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
條件運算子:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
無操作:_
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
(5)設定屬性值:
設定任意屬性值:th:attr
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf


設定值到指定的屬性:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
固定值布林屬性:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
(6)迭代器:
基本迭代器:th:each
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
狀態變數:index,count,size,current,even/odd,first/last
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
(7)條件語句:
th:if,th:unless
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf

Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
Switch:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
3.Thymeleaf與Spring boot整合
(1)模板佈局(我們在開發中可以看到頁面中有許多的公用片段)
方式一:定義和引用片段:th:insert
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
方式二:不使用th:fragment
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
th:insert,th:replace,th:include三者的區別
●th:insert它將簡單的插入指定的片段作為正文的主標籤
●th:replace用指定實際片段來替換其他主標籤
●th:include類似於insert,不常用,瞭解即可
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf


(2)屬性優先順序
(3)註釋:
解析器級別註釋(解析快中內容執行時會被刪除)
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
(4)內聯表示式:
[[.....]]或[(.....)]分別對應於th;text和th:utext
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
禁用內聯:
有時需要禁用這種機制,比如,想輸出[[.......]]或[(...)]文字內容
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
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專案,測試專案是否正常執行:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
專案建立成功後,我們匯入IDE中,開啟專案,我們編寫一個helloController,專案結構如下:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
測試專案是否能正常執行,我們新增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;
    }

}

接下來啟動的專案,專案正常啟動後,我們在瀏覽器,訪問頁面地址,觀察結果,:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
由此可以看出我們的專案正常執行,可以進入下一步的開發
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)後臺編碼:
首先展示專案後臺結構:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
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
展示前臺專案結構:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
公共程式碼片段—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>

我們啟動專案進行功能測試,截圖展示:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
點選建立使用者:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
點選提交,新增成功重定向到list.html頁面:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
點選名稱,展示詳細資訊:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
點選修改,跳轉到form.html頁面,並填寫修改資訊:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
點選提交重定向到list.html,頁面,可以發現資訊已經修改成功:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
接下來檢視詳細資訊
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf
點選刪除,重定向到list.html頁面:
Spring Boot整合Thymeleaf實戰筆記,系統學習Thymeleaf

觀察結果,我們發現數據信息刪除成功,專案展示完畢,thymeleaf+spring+mevan學習完畢