1. 程式人生 > >spring5+thymeleaf 模板語言

spring5+thymeleaf 模板語言

一、Thymeleaf 是個什麼?

簡單說, Thymeleaf 是一款用於渲染XML/XHTML/HTML5內容的模板引擎,類似JSP、Velocity、FreeMarker 等模板引擎它也可以輕易的與Spring MVC等Web框架進行整合作為Web應用的模板引擎。與其它模板引擎相比,它有如下三個極吸引人的特點:

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

  2. Thymeleaf 開箱即用的特性。它提供標準和spring標準兩種方言,可以直接套用模板實現JSTL、 OGNL表示式效果,避免每天套模板、該jstl、改標籤的困擾。同時開發人員也可以擴充套件和建立自定義的方言。

  3. Thymeleaf 提供spring標準方言和一個與 SpringMVC 完美整合的可選模組,可以快速的實現表單繫結、屬性編輯器、國際化等功能。

    二、標準表示式語法

  4. 變數 Thymeleaf模板引擎在進行模板渲染時,還會附帶一個Context存放進行模板渲染的變數,在模板中定義的表示式本質上就是從Context中獲取對應的變數的值:<p>Today is: <span th:text="${today}">13 february 2011</span>.</p>
    假設today的值為2016年7月14日,那麼渲染結果為:<p>Today is: 2016年7月14日.</p>。可見Thymeleaf的基本變數和JSP一樣,都使用${.}表示獲取變數的值。
  5. url 處理 URL在Web應用模板中佔據著十分重要的地位,需要特別注意的是Thymeleaf對於URL的處理是通過語法@{…}來處理的。 Thymeleaf支援絕對路徑URL:<a th:href="@{http://www.thymeleaf.org}">Thymeleaf</a> 同時也能夠支援相對路徑URL:

    另外,如果需要Thymeleaf對URL進行渲染,那麼務必使用th:href,th: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 '/order/details?orderId=3' (plus rewriting) -->
    <a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a>
    
    <!-- Will produce '/order/3/details' (plus rewriting) -->
    <a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>

    幾點說明: 上例中URL最後的(orderId=${o.id})表示將括號內的內容作為URL引數處理,該語法避免使用字串拼接,大大提高了可讀性@{...}表示式中可以通過{orderId}訪問Context中的orderId變數@{/order}是Context相關的相對路徑,在渲染時會自動新增上當前Web應用的Context名字,假設context名字為app,那麼結果應該是/app/order

    • 當前頁面相對路徑URL——user/login.html,通常不推薦這樣寫。
    • Context相關URL——/static/css/style.css
  6. 字串替換 很多時候可能我們只需要對一大段文字中的某一處地方進行替換,可以通過字串拼接操作完成:<span th:text="'Welcome to our application, ' + ${user.name} + '!'">一種更簡潔的方式是:<span th:text="|Welcome to our application, ${user.name}!|">當然這種形式限制比較多,|…|中只能包含變量表達式${…},不能包含其他常量、條件表示式等。
  7. 運算子 在表示式中可以使用各類算術運算子,例如+, -, *, /, %th:with="isEven=(${prodStat.count} % 2 == 0)" 邏輯運算子>, <, <=’,>=,==,!=都可以使用,唯一需要注意的是使用<,>,`時需要用它的HTML轉義符th:if="${prodStat.count} &gt; 1"th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')"
  8. 迴圈 渲染列表資料是一種非常常見的場景,例如現在有n條記錄需要渲染成一個表格<table>,該資料集合必須是可以遍歷的,使用th:each標籤:

    <body>
      <h1>Product list</h1>
    
      <table>
        <tr>
          <th>NAME</th>
          <th>PRICE</th>
          <th>IN STOCK</th>
        </tr>
        <tr th:each="prod : ${prods}">
          <td th:text="${prod.name}">Onions</td>
          <td th:text="${prod.price}">2.41</td>
          <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
        </tr>
      </table>
    
      <p>
        <a href="../home.html" th:href="@{/}">Return to home</a>
      </p>
    </body>

    可以看到,需要在被迴圈渲染的元素(這裡是)中加入th:each標籤,其中th:each="prod : ${prods}"意味著對集合變數prods進行遍歷,迴圈變數是prod在迴圈體中可以通過表示式訪問。

  9. 條件求值

    If/Unless

    Thymeleaf中使用th:ifth:unless屬性進行條件判斷,下面的例子中,<a>標籤只有在th:if中條件成立時才顯示:<a th:href="@{/login}" th:if=${session.user != null}>Login</a>th:unlessth:if恰好相反,只有表示式中的條件不成立,才會顯示其內容。

    Switch

    Thymeleaf同樣支援多路選擇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>
    </div>
  10. 預設屬性default可以用*表示:

    <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>
  11. Utilities

    為了模板更加易用,Thymeleaf還提供了一系列Utility物件(內置於Context中),可以通過#直接訪問: - #dates - #calendars - #numbers - #strings - arrays - lists - sets - maps - … 下面用一段程式碼來舉例一些常用的方法:

    #dates

    /*
     * 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()}
  12. #strings

    /*
     * 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)}
  13. 頁面即原型

    在Web開發過程中一個繞不開的話題就是前端工程師與後端工程師的協作,在傳統Java Web開發過程中,前端工程師和後端工程師一樣,也需要安裝一套完整的開發環境,然後各類Java IDE中修改模板、靜態資原始檔,啟動/重啟/重新載入應用伺服器,重新整理頁面檢視最終效果。

    但實際上前端工程師的職責更多應該關注於頁面本身而非後端,使用JSP,Velocity等傳統的Java模板引擎很難做到這一點,因為它們必須在應用伺服器中渲染完成後才能在瀏覽器中看到結果,而Thymeleaf從根本上顛覆了這一過程,通過屬性進行模板渲染不會引入任何新的瀏覽器不能識別的標籤,例如JSP中的<form:input>,不會在Tag內部寫表示式。整個頁面直接作為HTML檔案用瀏覽器開啟,幾乎就可以看到最終的效果,這大大解放了前端工程師的生產力,它們的最終交付物就是純的HTML/CSS/JavaScript檔案。

三、springs與thymeleaf整合