文章出處

在asp.net mvc 中, 有一個視圖解析器, 可以支持Razor語法. 使用起來, 是非常的方便, 并且, 寫在前臺頁面的后臺方法, 是可調試的. 

但是在java中, 目前我還沒有接觸到, 像.net vs 那么強大的功能. 

對于mvc來說, 視圖的解析, 是必不可少的. 實現的功能, 和上面是一樣的, 而且, 有很多種, 例如: jsp, freemarker, thymeleaf 等.

這里, 我主要記錄 thymeleaf 的一些學習筆記. 這里不牽涉原理, 只記錄使用方法.

一. 添加依賴

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

 這里如果只添加到這里, 引用的版本, 是比較低的, 如果要使用自己特定的版本, 只需要在 pom.xml 的properties 中指定版本就行了.

<thymeleaf.version>3.0.5.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.0.0</thymeleaf-layout-dialect.version>

 

二. spring boot 中, thymeleaf 的默認配置

這里首先看一下, 默認配置接收的類

/*
 * Copyright 2012-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.boot.autoconfigure.thymeleaf;

import java.nio.charset.Charset;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.MimeType;

/**
 * Properties for Thymeleaf.
 *
 * @author Stephane Nicoll
 * @since 1.2.0
 */
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {

    private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");

    private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");

    public static final String DEFAULT_PREFIX = "classpath:/templates/";

    public static final String DEFAULT_SUFFIX = ".html";

    /**
     * Check that the template exists before rendering it (Thymeleaf 3+).
     */
    private boolean checkTemplate = true;

    /**
     * Check that the templates location exists.
     */
    private boolean checkTemplateLocation = true;

    /**
     * Prefix that gets prepended to view names when building a URL.
     */
    private String prefix = DEFAULT_PREFIX;

    /**
     * Suffix that gets appended to view names when building a URL.
     */
    private String suffix = DEFAULT_SUFFIX;

    /**
     * Template mode to be applied to templates. See also StandardTemplateModeHandlers.
     */
    private String mode = "HTML5";

    /**
     * Template encoding.
     */
    private Charset encoding = DEFAULT_ENCODING;

    /**
     * Content-Type value.
     */
    private MimeType contentType = DEFAULT_CONTENT_TYPE;

    /**
     * Enable template caching.
     */
    private boolean cache = true;

    /**
     * Order of the template resolver in the chain. By default, the template resolver is
     * first in the chain. Order start at 1 and should only be set if you have defined
     * additional "TemplateResolver" beans.
     */
    private Integer templateResolverOrder;

    /**
     * Comma-separated list of view names that can be resolved.
     */
    private String[] viewNames;

    /**
     * Comma-separated list of view names that should be excluded from resolution.
     */
    private String[] excludedViewNames;

    /**
     * Enable MVC Thymeleaf view resolution.
     */
    private boolean enabled = true;

    ......
}

從這里可以看到, 默認的是 html 格式的, 且放在 classpath:/templates/ 目錄下. 一般情況下, 我們不需要再對thymeleaf進行配置, 但是在開發的過程中, 可能要屏蔽緩存功能.  最后我們要做的, 只是將路徑拼接進去就行了.

application.yml文件中, 可以禁用緩存.

spring:
  thymeleaf:
    cache: false

 

三. 基本使用

1. 表達式

  變量表達式: ${...}   

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

  URL表達式: @{...}  

  消息表達式: #{...} 

  片段表達式: ~{...}

2. 文字

  文本: '123', 'abc'

  數字: 1,2,0.5

  布爾: true, false

  空: null

3. 文本操作

  字符串連接: +

  文本替換: |雙豎線隔起來 ${name}|

4. 算數運算符

  二進制運算法(加減乘除,取模): +    -    *    /    %

5. 負號: -

6. 布爾運算符

  and   or    not    !

7. 比較和相等運算符

  比較運算符(這里建議使用英文字符代替 >  >=  <  <=)   gt    ge    lt     le

  相等運算符: ==   !=  

8. 條件運算符

  三元運算符:  if(...)? 'then' : 'else'

  if(...)? 'then'  這里沒有else, 因為else默認為 ''

  為空判斷   (aaa)?:bbb   如果aaa為空, 則使用bbb的值, 否則使用aaa

9. 啞操作符  _  (一個下劃線)

接下來對以上部分進行測試.

controller:

package org.elvin.learn.springboot.controller;

import org.elvin.learn.springboot.pojo.Book;
import org.joda.time.DateTime;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.thymeleaf.util.MapUtils;

import java.util.*;

@Controller
@RequestMapping("thy")
public class ThyController {

    @GetMapping("index")
    public String index(Model model) {
        model.addAttribute("book0", null);

        Book book = new Book("springmvc", new DateTime().toString("yyyy-MM-dd"), 10000L);
        model.addAttribute("book", book);

        Book book1 = new Book("springboot", new DateTime().toString("yyyy-MM-dd"), 21000L);
        model.addAttribute("book1", book1);

        model.addAttribute("color", "red");
        model.addAttribute("msg", "welcome");
        model.addAttribute("nowTime", new Date());       

        return "thy/index";
    }
}

 

html:

大體框架

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>Title</title>
    <!--@ { } 鏈接網址表達式, 會自動加入虛擬路徑-->
    <link th:href="@{/bootstrap-3.3.7/css/bootstrap.css}" rel="stylesheet"/>
    <link th:href="@{/bootstrap-3.3.7/css/bootstrap-theme.css}" rel="stylesheet"/>
    <style th:inline="css">
        /*通過[ [ $ { }]]的方式訪問model中的屬性*/
        .bgcolor {
            background-color: [[${color}]]
        }
    </style>
</head>
<body>


<script th:src="@{/js/jquery1.11.1/jquery-1.11.1.js}" type="text/javascript"></script>
<script th:src="@{/bootstrap-3.3.7/js/bootstrap.js}" type="text/javascript"></script>
<script th:inline="javascript">
    $(function () {
        var book = [[${book}]];
        console.log(book.name);
    });
</script>
</body>
</html>

數據準備:

在messages.properties中加入以下數據:

welcome=welcome here! {0}
hello={0} say hello to {1}
startWorkd=start from here

在templates中新建文件夾 common, 在下面建兩個文件 footer.html, header.html

<!DOCTYPE html>
<html  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Title</title>
</head>
<body>
    <div th:fragment="footerDiv">
        <p>common.footer 底部菜單</p>
    </div>
</body>
</html>

<!DOCTYPE html>
<html  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Title</title>
</head>
<body>
    <div id="headerDiv">
        <p>common.header 頭部菜單</p>
    </div>
</body>
</html>

 

接下來, 就是在里面添加內容了.

<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">URL表達式 / 消息表達式</h3>
        <!--
            URL 表達式
        -->
        <a style="background-color: #0f0f0f" th:href="@{/thy/index(lang='en_US')}">English(US)</a>
        <a style="background-color: #0f0f0f"
           th:href="@{http://localhost:8080/springboot/thy/index?lang=zh_CN}">簡體中文</a>
    </div>
    <div class="panel-body">
        <!--
       1. # { }消息表達式 : 替換文本
       1.1 文本中, 預留參數
       1.2 消息key用變量替換
   -->
        <!--1.1 在消息中加入參數, 多個參數, 在傳值的時候用逗號隔開-->
        <p th:text="#{startWorkd}"></p>
        <p th:utext="#{welcome(${book.name})}">hahaha</p>
        <p th:utext="#{hello(${book.name}, ${bookList[1].name})}">hahaha</p>
        <!--1.2 消息用變量替換-->
        <p th:utext="#{${msg}(${book.name})}">hahaha</p>
    </div>
</div>

<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">選擇變量表達式</h3>
    </div>
    <div class="panel-body">
        <!-- 選擇變量表達式 * { } -->
        <p th:object="${book0 ?: book1}">
            <span th:text="*{name}"></span>
            <span th:text="*{price gt 10000}?'大于100元':'小于等于100元'"></span>
            <span th:text="*{publishTime.length() ge 10}?'時間長度過長'"></span>
        </p>

        <p>
            <!--星號語法計算所選對象而不是整個上下文的表達式,
            所以, 只要沒有選定的對象, $ 和 * 語法就完全相同-->
            <span th:text="*{book.name}"></span>
            <span th:text="*{book.price} / 100 + '元'"></span>
            <span th:text="*{book.publishTime}"></span>
        </p>
    </div>
</div>

<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">選擇變量表達式</h3>
    </div>
    <div class="panel-body">
        <div style="display:none">
            <!--assert 都成立才會執行, 否則拋出異常
             th:assert="${!#strings.isEmpty(onevar)},${!#strings.isEmpty(twovar)}"
            -->
            <!--這里將模板定義成了函數的方式,
            temp1表示函數名, name1, name2 表示參數, 不同的是, 可以不寫在這里, 直接在下面用的時候會寫也可以-->
            <div th:fragment="temp1(name1, name2)">
                <span th:utext="|book: ${name1} , book1: ${name2}|"></span>
            </div>
            <!--th:assert="${price > 100}, ${!#strings.isEmpty(name)}"-->
            <div th:fragment="temp2">
                <span th:utext="'book: ' + ${name} + ', price: ' + ${price}"></span>
            </div>
        </div>

        <!--replace可以替換能成insert,但是他們之間是有區別的, insert會保留當前標簽-->
        <div th:replace=":: temp1(${book.name}, ${book1.name})"></div>
        <div th:insert="~{:: temp2(name=${book.name}, price=${book.price})}"></div>
        <!--include官方3.0后不推薦使用-->
        <div th:include=":: temp1(name1=${book.name}, name2=${book1.name})"></div>

        <!--引入外部的文件中的某一部分內容-->
        <div th:insert="~{common/header :: #headerDiv}"></div>
        <div th:insert="~{common/footer :: footerDiv}"></div>

        <!--這里可以通過判斷表達式來控制插入什么, 或者什么也不插入-->
        <div th:insert="_">啥也不插入, 也不替換任何東西</div>
        <div th:insert="${book0 == null}? ~{:: temp1(${book.name}, ${book1.name})}:~{}"></div>
    </div>
</div>

 

結果:

 

 

 

 

 

 

 

 

  

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()