從.Net到Java學習第九篇——SpringBoot下Thymeleaf


從.Net到Java學習系列目錄

Thymeleaf概述

  Thymeleaf 是一個流行的模板引擎,該模板引擎采用java語言開發。模板引擎是一個技術名稱,是跨領域平台的概念,在java語言體系下有模板引擎,在C#、PHP語言體系下也有模板引擎,甚至在JavaScript中也會用到模板引擎技術。
Java生態下的模板引擎有Thymeleaf 、Freemaker、Velocity、Beetl(國產)等。Thymeleaf模板既能用於web環境下,也能用於非web環境下,在非web環境下,它能直接顯示模板上的靜態數據,在web環境下,它能像JSP一樣從后台接收數據並替換掉模板上的靜態數據。.net下面的razor也是一個模板引擎。

Thymeleaf它是基於HTML的,以HTML標簽為載體,Thymeleaf要寄托在HTML的標簽下實現對數據的展示。
Thymeleaf的官方網站:http://www.thymeleaf.org
Spring boot集成了Thymeleaf模板技術,並且Spring boot官方也推薦使用
Thymeleaf來替代JSP技術。
Thymeleaf是另外的一種模板技術,它本身並不屬於spring boot,
srpingboot只是很好的集成了這種模板技術,作為前端頁面的數據展示。

Spring Boot集成Thymeleaf配置

(1)修改pom.xml,在Maven中引入Thymeleaf的依賴:

        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

(2)在Spring boot的核心配置文件application.yml中對Thymeleaf進行配置:

spring:
  profiles:
    active: test
 thymeleaf: cache: false #開發階段,建議關閉Thymeleaf的緩存 mode: LEGACYHTML5 #使用遺留的html5以去掉對html標簽的校驗

在使用Spring boot的過程中,如果使用thymeleaf作為模板文件,則要求HTML格式必須為嚴格的html5格式,所有標簽必須有結束標簽,否則會報錯。如果不想對標簽進行嚴格的驗證,使用spring.thymeleaf.model=LEGACYHTML5去掉驗證,去掉該驗證還需要引入許下的依賴,否則會報錯。

        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.22</version>
        </dependency>

 (3)新建一個控制器ThymeleafController去映射到模板頁

@Controller
public class ThymeleafController {
    @GetMapping("/index")
    public String index(Model model){
        model.addAttribute("msg","Spring boot集成Thymeleaf");
        return "index"; //返回的是一個頁面,可以省略后綴.html
    }
}

(4)在src/main/resources的templates下面新建一個index.html頁面用於數據展示,HTML頁面的<html>元素中葯記得加入以下屬性:

<html xmlns:th="http://www.thymeleaf.org">

 index.html源碼如下:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"><!--引入thymeleaf-->
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p th:text="${msg}">你好</p>
</body>
</html>

 Springboot使用thymeleaf作為視圖展示,約定將模板文件放置在src/main/resources/templates目錄下,靜態資源放置在src/main/resources/static目錄下

運行IDEA項目

如果不啟動spring boot直接在瀏覽器中瀏覽這個頁面

Thymeleaf標准變量表達式

語法:${...}

變量表達式用於訪問容器(tomcat)上下文環境中的變量,功能和JSTL中的${}相同。Thymeleaf中的變量表達式使用${變量名}的方式獲取其中的數據。

新建實體類User

package com.yujie.entity;

public class User {
    private String name;
    private String sex;
    private Integer age;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

在Spring mvc的Controller中使用向前端傳輸數據,ThymeleafController代碼如下:

    @GetMapping("/user")
    public String user(Model model){
        User user=new User();
        user.setAge(21);
        user.setEmail("zouyujie@126.com");
        user.setName("玉傑");
        model.addAttribute("user",user);
        return "user";
    }

templates目錄下面,新建一個user.html頁面,前端接收代碼:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"><!--引入thymeleaf-->
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p>用戶信息如下:</p>
<div th:text="${user.name}"></div>
<div th:text="${user.age}"></div>
<div th:text="${user.email}"></div>
</body>
</html>

瀏覽

選擇變量表達式

選擇變量表達式,也叫星號變量表達式,使用th:object屬性來綁定對象,比如:

<p>分割線——選擇變量表達式</p>
<div th:object="${user}">
    <div th:text="*{name}"></div>
    <div th:text="*{age}"></div>
    <div th:text="*{email}"></div>
</div>

 繼續



選擇變量表達式首先使用th:object來綁定后台傳來的user對象,然后使用*來代表這個對象,后面{}中的值是此對象中的屬性。
選擇變量表達式*{...}是另一種類似於變量表達式${...}表示變量的方法。
選擇變量表達式在執行時是在選擇的對象上求解,而${...}是在上下文的變量Model上求解。
通過th:object屬性指明選擇變量表達式的求解對象。
標准變量表達式和選擇變量表達式可以混合在一起使用,比如:

<div th:object="${user}">
    <div th:text="*{name}"></div>
    <div th:text="*{age}"></div>
    <div th:text="${user.email}"></div>
</div>

也可以不使用th:object進行對象的選擇,而直接使用*{...}獲取數據,比如:

<p>不使用th:object</p>
<div>
    <div th:text="*{user.name}"></div>
    <div th:text="*{user.age}"></div>
    <div th:text="*{user.email}"></div>
</div>

Thymeleaf的URL表達式

語法:@{...}

URL表達式可用於<script src="...">、<link href="...">、<a href="...">等
1.絕對URL,比如:

<a href="index.html" th:href="@{'http://localhost:8080/user?name='+${user.name}}">index</a>

2.相對URL,相對於頁面,比如:

<a href="index.html" th:href="@{'user?name='+${user.name}}">index</a>

3.相對URL,相對於項目上下文,比如:

<a href="index.html" th:href="@{'/user?name='+${user.name}}">index</a>

項目的上下文名會自動添加,我們可以看下html運行的源碼。

thymeleaf的常用屬性

thymeleaf的常用屬性:
th:action
th:each
th:href
th:id
th:if
th:unless
th:switch/th:case
th:object
th:src
th:text
th:value
th:attr
th:onclick
th:style
th:method
th:name
th:inline
這些標記大多數和html的標記名稱是一樣的。

thymeleaf表達式基本對象

模板引擎提供了一組內置的對象,這些內置的對象可以直接在模板中使用,這些對象由#號開始引用。

#request

相當於HttpServletRequest對象,這是3.x版本,若是2.x版本使用#httpServletRequest
${#request.getContextPath()}
${#request.getAttribute("name")}

#session

相當於HttpSession
對象,這是3.x版本,若是2.x版本使用#httpSession,需要在后頭controller中設置session,
${#session.getAttribute("phone")}
${#session.id}

thymeleaf表達式功能對象

1.模板引擎提供的一組功能性內置對象,可以在模板中直接使用這些對象提供的功能方法。
2.工作中常使用的數據類型,如集合、時間、數值,可以使用thymeleaf提供的功能性對象來處理它們。
3.內置功能對象前都需要加#號,內置對象一般都以s結尾。

  • #dates:java.util.Date對象的實用方法,<span th:text="${#dates.format(curDate,'yyyy-MM-dd HH:mm:ss')}"></span>
  • #calendars:和dates類似,但是是java.util.Calendar對象。
  • #numbers:格式化數據對象的實用方法。
  • #strings:字符串對象的實用方法。contains,startsWith,prepending/appending等。
  • #objects:對objects操作的實用方法。
  • #bools:對布爾值求值的實用方法。
  • #arrays:數組的實用方法。
  • #lists:list的實用方法.
  • #sets:set的實用方法.
  • #maps:map的實用方法
  • #aggregates:對數組或集合創建聚合的實用方法。

還有條件表達式等等,更多內容可以參考thymeleaf的官網:http://www.thymeleaf.org

thymeleaf th:text 不顯示標簽

解決辦法,通過追加th:remove屬性,演示如下:

<span th:text="${title}" th:remove="tag"></span>

thymeleaf布局

thymeleaf既然和razor一樣,那么肯定也有布局頁,也就是母版頁。thymeleaf的layout常用的有兩種方式用法:

第一種 th:include||th:replace||th:insert

將頁面里的每個部分都分成塊 -> fragment 使用 th:include 和 th:replace 來引入頁面
這種用法沒有layout的概念, 因為每個部分都是 fragment

  • th:insert 3.0+版本新加的
  • th:replace 2.0+ 3.0+都可用
  • th:include 這個在3.0版本已經不建議使用

 它們的區別,

<footer th:fragment="copy"> 
  © 2011 The Good Thymes Virtual Grocery
</footer>

調用方式:

<!-- 引用html段 --> 
<body>
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>
</body>

最終結果如下:

<!-- 最終結果 --> 
<body>
<!-- th:insert,div tag內部插入html段 -->
<div> <footer> © 2011 The Good Thymes Virtual Grocery </footer> </div>
<!-- th:replace,使用html段直接替換 div tag -->
<footer> © 2011 The Good Thymes Virtual Grocery </footer>
<!-- th:include,div tag內部插入html段(僅保留段子元素的內容) -->
<!-- 仔細對比 th:insert 與 th:include的結果 -->
<div> © 2011 The Good Thymes Virtual Grocery </div>
</body>

 第二種 布局頁

寫一個layout.html頁面,當作頁面的基礎頁面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
<header>這是頭部</header>
<div layout:fragment="content"></div>
<footer>這是底部</footer>
</body>
</html>

新建一個子頁面layoutTest.html,在子頁面里使用 layout:decorator 來將子頁面里的內容加入到 layout.html里去

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" layout:decorator="common/layout">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
<div layout:fragment="content">
    <h2>我是文本內容</h2>
</div>
</body>
</html>

控制器中添加一個測試方法

    @RequestMapping("/layout")
    public String layout(Model model) {
        return "layoutTest";
    }

運行結果如下:

這樣在layout.html里引入的css,js,imgs都可以在子頁面里用了,而且在子頁面里還可以引入子頁面需要用到的css,js,imgs, 就很方便了,所以這也是推薦的方式。
模板傳值,假如要往header.html里傳入一個tab來區別應該高亮哪個菜單,可以使用下面的寫法實現, 創建header.html,然后在布局頁layout.html定一個css樣式。

header.html代碼如下:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
<header th:fragment="header (tab)">
    <ul>
        <li>
            <span th:class="${tab eq 'news'} ? active">news</span>
        </li>
        <li>
            <span th:class="${tab eq 'blog'} ? active">blog</span>
        </li>
        <li>
            <span th:class="${tab eq 'post'} ? active">post</span>
        </li>
    </ul>
</header>
</body>
</html>

修改layout.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
    <style type="text/css">
        .active {background-color: green;}
    </style>
</head>
<body>
<div th:include="common/header :: header(tab='blog')"></div>
<div layout:fragment="content"></div>
<footer>這是底部</footer>
</body>
</html>

運行結果如下:

Spring-Boot配置文件thymeleaf模板配置項(常用配置項為紅色

參數 介紹
spring.thymeleaf.cache = true 啟用模板緩存(開發時建議關閉)
spring.thymeleaf.check-template = true 檢查模板是否存在,然后再呈現
spring.thymeleaf.check-template-location = true 檢查模板位置是否存在
spring.thymeleaf.content-type = text/html Content-Type值
spring.thymeleaf.enabled = true 啟用MVC Thymeleaf視圖分辨率
spring.thymeleaf.encoding = UTF-8 模板編碼
spring.thymeleaf.excluded-view-names = 應該從解決方案中排除的視圖名稱的逗號分隔列表
spring.thymeleaf.mode = HTML5 應用於模板的模板模式。另請參見StandardTemplateModeHandlers
spring.thymeleaf.prefix = classpath:/templates/ 在構建URL時預先查看名稱的前綴
spring.thymeleaf.suffix = .html 構建URL時附加查看名稱的后綴
spring.thymeleaf.template-resolver-order = 鏈中模板解析器的順序
spring.thymeleaf.view-names = 可以解析的視圖名稱的逗號分隔列表

參考:https://tomoya92.github.io/2017/03/09/thymeleaf-layout/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM