1. 程式人生 > 實用技巧 >Thymeleaf——入門與基本概述

Thymeleaf——入門與基本概述

一、概述

  1.是什麼

    簡單說, Thymeleaf 是一個跟 Velocity、FreeMarker 類似的模板引擎,它可以完全替代 JSP 。

  2.feature

    1.Thymeleaf 在有網路和無網路的環境下皆可執行,即它可以讓美工在瀏覽器檢視頁面的靜態效果,也可以讓程式設計師在伺服器檢視帶資料的動態頁面效果。這是由於它支援 html 原型,然後在 html 標籤裡增加額外的屬性來達到模板+資料的展示方式。瀏覽器解釋 html 時會忽略未定義的標籤屬性,所以 thymeleaf 的模板可以靜態地執行;當有資料返回到頁面時,Thymeleaf 標籤會動態地替換掉靜態內容,使頁面動態顯示。

   2.Thymeleaf 開箱即用的特性。它提供標準和spring標準兩種方言,可以直接套用模板實現JSTL、 OGNL表示式效果,避免每天套模板、該jstl、改標籤的困擾。同時開發人員也可以擴充套件和建立自定義的方言。    3. Thymeleaf 提供spring標準方言和一個與 SpringMVC 完美整合的可選模組,可以快速的實現表單繫結、屬性編輯器、國際化等功能。

  3.文件

    官方教程http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#what-is-thymeleaf

    推薦教程http://blog.didispace.com/springbootweb/

         http://blog.csdn.net/u012706811/article/details/52185345

二、HelloWorld

  1.引入依賴

    springboot直接引入:

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

    非springboot專案使用如下依賴:

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>2.1.4</version>
</dependency>

  預設的模板對映路徑是:src/main/resources/templates,

  springboot1.4之後,可以使用thymeleaf3來提高效率,並且解決標籤閉合問題,配置方式:

 <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- set thymeleaf version -->
    <thymeleaf.version>3.0.0.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.0</thymeleaf-layout-dialect.version>
    <!--set java version-->
    <java.version>1.8</java.version>
  </properties>

   之前的model/modelMap/modelAndView等頁面資料傳遞參考之前隨筆:點選檢視

    快速回顧:

package com.learndemo.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping(value = "/return")
public class LearnReturnType {

    /**
     * Model本身不能設定頁面跳轉的url地址別名或者物理跳轉地址,那麼我們可以通過控制器方法的返回值來設定跳轉url
     * 地址別名或者物理跳轉地址
     * 
     * @param model
     *            一個介面, 其實現類為ExtendedModelMap,繼承了ModelMap類
     * @return 跳轉url地址別名或者物理跳轉地址
     */
    @RequestMapping(value = "/index1")
    public String index1(Model model) {
        model.addAttribute("result", "後臺返回index1");
        return "result";
    }

    /**
     * ModelMap物件主要用於傳遞控制方法處理資料到結果頁面,類似於request物件的setAttribute方法的作用。 用法等同於Model
     * 
     * @param model
     * @return 跳轉url地址別名或者物理跳轉地址
     */

    @RequestMapping(value = "/index2")
    public String index2(ModelMap model) {
        model.addAttribute("result", "後臺返回index2");
        return "result";
    }

    /**
     * ModelAndView主要有兩個作用 設定轉向地址和傳遞控制方法處理結果資料到結果頁面
     * @return 返回一個模板檢視物件
     */
    @RequestMapping(value = "/index3")
    public ModelAndView index3() {
        ModelAndView mv = new ModelAndView("result");
        // ModelAndView mv = new ModelAndView();
        // mv.setViewName("result");
        mv.addObject("result", "後臺返回index3");
        return mv;
    }

    /**
     * map用來儲存遞控制方法處理結果資料,通過ModelAndView方法返回。
     * 當然Model,ModelMap也可以通過這種方法返回
     * @return 返回一個模板檢視物件
     */
    @RequestMapping(value = "/index4")
    public ModelAndView index4() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("result", "後臺返回index4");
        return new ModelAndView("result", map);
    }
}

  2.配置thymeleaf檢視解析器

    這點與springMVC是相類似的:

#thymeleaf start
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
#開發時關閉快取,不然沒法看到實時頁面
spring.thymeleaf.cache=false
#thymeleaf end

    實際專案中可能會有不太嚴格的HTML格式,此時設定mode=HTML5將會對非嚴格的報錯,可以參考以下配置:

spring.thymeleaf.mode=LEGACYHTML5
你可能會發現在預設配置下,thymeleaf對.html的內容要求很嚴格,比如<meta charset="UTF-8" />,
如果少最後的標籤封閉符號/,就會報錯而轉到錯誤頁。也比如你在使用Vue.js這樣的庫,然後有<div v-cloak></div>這樣的html程式碼,
也會被thymeleaf認為不符合要求而丟擲錯誤。 因此,建議增加下面這段: spring.thymeleaf.mode = LEGACYHTML5 spring.thymeleaf.mode的預設值是HTML5,其實是一個很嚴格的檢查,改為LEGACYHTML5可以得到一個可能更友好親切的格式要求。 需要注意的是,LEGACYHTML5需要搭配一個額外的庫NekoHTML才可用。
  1. <dependency>
  2. <groupId>net.sourceforge.nekohtml</groupId>
  3. <artifactId>nekohtml</artifactId>
  4. <version>1.9.22</version>
  5. </dependency>

最後重啟專案就可以感受到不那麼嚴格的thymeleaf了。

  這樣,需要的配置項如下:

# 一項是非嚴格的HTML檢查,一項是禁用快取來獲取實時頁面資料,其他採用預設項即可
  thymeleaf:
    mode: LEGACYHTML5
    cache: false

  //完整配置項參考類ThymeleafProperties

  3。編寫控制器

/**
 * 測試demo的controller
 *
 * @author zcc ON 2018/2/8
 **/
@Controller
public class HelloController {
    private static final Logger log = LoggerFactory.getLogger(HelloController.class);

    @GetMapping(value = "/hello")
    public String hello(Model model) {
        String name = "jiangbei";
        model.addAttribute("name", name);
        return "hello";
    }
}

  4.編寫模板html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
    <!--/*@thymesVar id="name" type="java.lang.String"*/-->
    <p th:text="'Hello!, ' + ${name} + '!'">3333</p>
</body>
</html>

  其中,註釋是通過alt+enter進行自動生成的,便於IDEA補全,如果不加,IDEA將會報錯cannot reslove,

  當然也可以通過如下方式解決,解決之前推薦在maven專案中reimport一下!(據說新版本的IDEA中已經修復此問題,待更新至2017.3以後)

  5.測試

  

三、基礎語法

  1.建立HTML

    由上文也可以知道需要在html中新增:

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

    這樣,下文才能正確使用th:*形式的標籤!

  2.獲取變數值${...}

    通過${…}進行取值,這點和ONGL表示式語法一致!

  <!--/*@thymesVar id="name" type="java.lang.String"*/-->
    <p th:text="'Hello!, ' + ${name} + '!'">3333</p>

   選擇變量表達式*{...}

<div th:object="${session.user}">
    <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
    <p>Surname: <span th:text="*{lastName}">Pepper</span>.</p> 
    <p>Nationality: <span th:text={nationality}">Saturn</span>.</p>
</div> 
等價於
<div>
    <p>Name: <span th:text="${session.user.firstName}">Sebastian</span>.</p> 
    <p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p> 
    <p>Nationality: <span th:text="${session.user.nationality}">Saturn</span>.</p>
</div>

    至於p裡面的原有的值只是為了給前端開發時做展示用的.這樣的話很好的做到了前後端分離。

    這也是Thymeleaf非常好的一個特性:在無網路的情況下也能執行,也就是完全可以前端先寫出頁面,模擬資料展現效果,後端人員再拿此模板修改即可!

  3.連結表示式: @{…}

    用來配合link src href使用的語法,類似的標籤有:th:hrefth:src

<!-- Will produce 'http://localhost:8080/gtvg/order/details?orderId=3' (plus rewriting) --> 

<a href="details.html" th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a> <!-- Will produce '/gtvg/order/details?orderId=3' (plus rewriting) --> <a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a> <a href="details.html" th:href="@{order/{orderId}/details(orderId=${o.id})}">Content路徑,預設訪問static下的order資料夾</a>

  4.文字替換

<span th:text="'Welcome to our application, ' + ${user.name} + '!'">

  或者下面的表達方式:(只能包含表示式變數,而不能有條件判斷等!)

<span th:text="|Welcome to our application, ${user.name}!|">

  5.運算子

    數學運算

  • 二元操作:+, - , * , / , %
  • 一元操作: - (負)

    邏輯運算

  • 一元 : and or
  • 二元 : !,not

    比較運算(為避免轉義尷尬,可以使用括號中的英文進行比較運算!)

  • 比較:> , < , >= , <= ( gt , lt , ge , le )
  • 等於:== , != ( eq , ne )

    條件運算

  • If-then: (if) ? (then)
  • If-then-else: (if) ? (then) : (else)
  • Default: (value) ?: (defaultvalue)
  • 'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))

    6.條件

   if/unless

   使用th:if和th:unless屬性進行條件判斷,th:unless於th:if恰好相反,只有表示式中的條件不成立,才會顯示其內容。

<a th:href="@{/login}" th:unless=${session.user != null}>Login</a>

   switch

<div th:switch="${user.role}">
  <p th:case="'admin'">User is an administrator</p>
  <p th:case="#{roles.manager}">User is a manager</p>
  <p th:case="*">User is some other thing</p>
</div>

  7.迴圈

    通過th:each

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
    <!-- 不存在則忽略,顯示hello null!(可以通過預設值進行設定)-->
    <p th:text="'Hello ' + (${name}?:'admin')">3333</p>
    <table>
        <tr>
            <th>ID</th>
            <th>NAME</th>
            <th>AGE</th>
        </tr>
        <tr th:each="emp : ${empList}">
            <td th:text="${emp.id}">1</td>
            <td th:text="${emp.name}">海</td>
            <td th:text="${emp.age}">18</td>
        </tr>
    </table>
</body>
</html>

    後臺:

@GetMapping(value = "/hello")
    public String hello(Model model) {
        List<Emp> empList = new ArrayList<>();
        empList.add(new Emp(1, "校長", 24));
        empList.add(new Emp(2, "書記", 28));
        empList.add(new Emp(3, "小海", 25));
        model.addAttribute("empList", empList);
        return "hello";
    }

    效果:

    

  更多迴圈深入,iterStat等示例,參考http://blog.csdn.net/sun_jy2011/article/details/40710429

  8.內建物件Utilites

    一般不推薦在前端進行這些處理,前端頁面以減少邏輯為宜

#dates :

utility methods for java.util.Date objects: formatting, component extraction, etc. #calendars : analogous to #dates , but for java.util.Calendar objects.

#numbers :
utility methods for formatting numeric objects.

#strings : 
utility methods for String objects: contains, startsWith, prepending/appending, etc. #objects : utility methods for objects in general.

#bools : 
utility methods for boolean evaluation. #arrays : utility methods for arrays.

#lists :
utility methods for lists.

#sets : 
utility methods for sets.

#maps : 
utility methods for maps.

#aggregates : 
utility methods for creating aggregates on arrays or collections.

#messages : 
utility methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{...} syntax.

#ids : 
utility methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).

  常用示例:

/*
 * Format date with the specified pattern
 * Also works with arrays, lists or sets
 */
${#dates.format(date, 'dd/MMM/yyyy HH:mm')}
${#dates.arrayFormat(datesArray, 'dd/MMM/yyyy HH:mm')}
${#dates.listFormat(datesList, 'dd/MMM/yyyy HH:mm')}
${#dates.setFormat(datesSet, 'dd/MMM/yyyy HH:mm')}

/*
 * Create a date (java.util.Date) object for the current date and time
 */
${#dates.createNow()}

/*
 * Create a date (java.util.Date) object for the current date (time set to 00:00)
 */
${#dates.createToday()}
/*
 * Check whether a String is empty (or null). Performs a trim() operation before check
 * Also works with arrays, lists or sets
 */
${#strings.isEmpty(name)}
${#strings.arrayIsEmpty(nameArr)}
${#strings.listIsEmpty(nameList)}
${#strings.setIsEmpty(nameSet)}

/*
 * Check whether a String starts or ends with a fragment
 * Also works with arrays, lists or sets
 */
${#strings.startsWith(name,'Don')}                  // also array*, list* and set*
${#strings.endsWith(name,endingFragment)}           // also array*, list* and set*

/*
 * Compute length
 * Also works with arrays, lists or sets
 */
${#strings.length(str)}

/*
 * Null-safe comparison and concatenation
 */
${#strings.equals(str)}
${#strings.equalsIgnoreCase(str)}
${#strings.concat(str)}
${#strings.concatReplaceNulls(str)}

/*
 * Random
 */
${#strings.randomAlphanumeric(count)}

  完整參考點選檢視

四、常用標籤

  

   //類似於th:object和th:field等進行表單引數繫結還是很有用的!使用與注意事項,參見:這裡

   參考博文https://www.cnblogs.com/hjwublog/p/5051732.html

本文轉載自{---江北}的部落格,原文地址:https://www.cnblogs.com/jiangbei/p/8462294.html