SpringBoot系列記錄(六)——SpringBoot整合thymeleaf並實現熱部署

前言

  • Thymeleaf是用來開發Web和獨立環境項目的服務器端的Java模版引擎

  • Spring官方支持的服務的渲染模板中,並不包含jsp。而是Thymeleaf和Freemarker等,而Thymeleaf與SpringMVC的視圖技術,及SpringBoot的自動化配置集成非常完美,幾乎沒有任何成本,你只用關注Thymeleaf的語法即可。

  • Thymeleaf支持html原型,瀏覽器解釋 html 時會忽略未定義的標籤屬性,所以 thymeleaf 的模板可以靜態地運行;當有數據返回到頁面時,Thymeleaf 標籤會動態地替換掉靜態內容,使頁面動態顯示

POM.XML

這裏添加了spring-boot-devtools來使Spring Boot應用支持熱部署

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional> <!-- 這個需要爲 true 熱部署纔有效 -->
        </dependency>
        <!-- spring-boot-starter-thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

說明:

(1) devtools可以實現頁面熱部署(即頁面修改後會立即生效,這個可以直接在application.properties文件中配置spring.thymeleaf.cache=false來實現),實現類文件熱部署(類文件修改後不會立即生效),實現對屬性文件的熱部署。
即devtools會監聽classpath下的文件變動,並且會立即重啓應用(發生在保存時機),注意:因爲其採用的虛擬機機制,該項重啓是很快的
(2)配置了true後在修改java文件後也就支持了熱啓動,不過這種方式是屬於項目重啓(速度比較快的項目重啓),會清空session中的值,也就是如果有用戶登陸的話,項目重啓後需要重新登陸。默認情況下,/META-INF/maven/META-INF/resources/resources/static/templates/public這些文件夾下的文件修改不會使應用重啓,但是會重新加載(devtools內嵌了一個LiveReload server,當資源發生改變時,瀏覽器刷新)。

application.properties

#thymeleaf 配置
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html
#緩存設置爲false, 這樣修改之後馬上生效,便於調試
spring.thymeleaf.cache=false
#設置重啓的目錄
#spring.devtools.restart.additional-paths: src/main/java
#classpath目錄下的文件夾內容修改不重啓
#spring.devtools.restart.exclude: static/**
#上下文
#server.context-path=/thymeleaf

IDEA設置

當我們修改了Java類後,IDEA默認是不自動編譯的,而spring-boot-devtools又是監測classpath下的文件發生變化纔會重啓應用,所以需要設置IDEA的自動編譯:

(1)File-Settings-Compiler-Build Project automatically

(2)ctrl + shift + alt + /,選擇Registry,勾上 Compiler autoMake allow when app running

 

 此時實現的效果就是:修改類和配置文件應用會重啓,修改頁面應用不會重啓,但會重新加載,頁面會刷新。

通常情況下我不希望一修改它就重啓,所以不使用自動編譯,而是手動使用Ctrl+F9來重新編譯

測試ThymeLeaf

首先在templates下新建index.html頁面,如果沒有templates文件夾就自己新建一個

index.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>首頁</title>
</head>
<body>
<p th:text="${tips}"></p>
</body>
</html>

controller:

@Controller
@RequestMapping("/indexManage")
public class IndexController {

    @RequestMapping("/toIndex")
    public String toIndex(Model model){
        model.addAttribute("tips","Hello Thymeleaf");
        return "index";
    }
}

訪問:http://localhost:8080/indexManage/toIndex

擴展:Thymeleaf其他用法

  • thymeleaf引入js、css文件:
<script type="text/javascript" src="../js/jquery.js" th:src="@{../js/jquery.js}"></script>

使用 @這種方式引入,在渲染後的html 裏會自動生成 上下文路徑,此demo沒有上下文路徑。
 如果使用瀏覽器直接打開當前的 hello.html, 依然可以看到css 和 js 效果,因爲前面正常的src語句會起作用

  • 幾種常用的語法

1、獲取對象的屬性值

  新建POJO

public class Student {

    private Integer id;

    private String sname;

    private Integer age;

    getter...  setter...

}

修改Controller: 

@Controller
@RequestMapping("/indexManage")
public class IndexController {

    @RequestMapping("/toIndex")
    public String toIndex(Model model){
        Student student = new Student();
        student.setSname("亞瑟");
        model.addAttribute("student",student);
        return "index";
    }
}

在頁面中獲取對象的屬性值

你好!<p th:text="${student.sname}"></p>

2、包含其他頁面

th:fragment   th:replace

新建include.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<footer th:fragment="footerOne">
Copyright
</footer>
<footer th:fragment="footerTwo(start,end)">
    <p th:text="|${start} - ${end} All Rights Reserved|"></p>
</footer>
</body>
</html>

 在index頁面使用

<div>
    <div th:replace="include::footerOne"></div>
    <div th:replace="include::footerTwo(2014,2020)"></div>
</div>

3、條件判斷 th:if

Thymeleaf 的條件判斷是 通過 th:if 來做的,只有爲真的時候,纔會顯示當前元素

在model中添加一個boolean數據

boolean flag = true;
model.addAttribute("flag",flag);

在index頁面中外層div使用:

<div th:if="${flag}">
    <div th:replace="include::footerOne"></div>
    <div th:replace="include::footerTwo(2014,2020)"></div>
</div>

取反可以用th:if="${not flag}, 或者用th:unless="${flag}

 不只是布爾值的 true 和 false, th:if 表達式返回其他值時也會被認爲是 true 或 false,規則如下:
boolean 類型並且值是 true, 返回 true
數值類型並且值不是 0, 返回 true
字符類型(Char)並且值不是 0, 返回 true
String 類型並且值不是 "false", "off", "no", 返回 true
不是 boolean, 數值, 字符, String 的其他類型, 返回 true
值是 null, 返回 false

4、th:each 遍歷

修改controller    記得在Student中添加構造方法

  @RequestMapping("/toIndex")
    public String toIndex(Model model){
       List<Student> students = new ArrayList<>();
        students.add(new Student(1,"張三",16));
        students.add(new Student(2,"李四",17));
        students.add(new Student(3,"王五",18));
        model.addAttribute("students",students);
        return "index";
    }

index頁面:

<table>
    <thead>
    <tr>
        <th>id</th>
        <th>姓名</th>
        <th>年齡</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="student: ${students}">
        <td th:text="${student.id}"></td>
        <td th:text="${student.sname}"></td>
        <td th:text="${student.age}"></td>
    </tr>
    </tbody>
</table>

 更多用法在後續的實戰篇再說吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章