Thymeleaf

在这里插入图片描述

Thymeleaf

概述

Thymeleaf 是一个流行的模板引擎,该模板引擎采用 Java 语言开发。

模板引擎是一个技术名词,是跨领域跨平台的概念,在 Java 语言体系下有模板引擎, 在 C#、PHP 语言体系下也有模板引擎,甚至在 JavaScript 中也会用到模板引擎技术,Java 生 态下的模板引擎有 Thymeleaf 、Freemaker、Velocity、Beetl(国产) 等。

Thymeleaf 对网络环境不存在严格的要求,既能用于 Web 环境下,也能用于非 Web 环境下。在非 Web 环境下,他能直接显示模板上的静态数据;在 Web 环境下,它能像 Jsp 一 样从后台接收数据并替换掉模板上的静态数据。它是基于 HTML 的,以 HTML 标签为载体, Thymeleaf 要寄托在 HTML 标签下实现。

SpringBoot 集成了 Thymeleaf 模板技术,并且 Spring Boot 官方也推荐使用 Thymeleaf 来替代 JSP 技术,Thymeleaf 是另外的一种模板技术,它本身并不属于 Spring Boot,Spring Boot 只是很好地集成这种模板技术,作为前端页面的数据展示。在过去的 Java Web 开发中,我们往往会选择使用 Jsp 去完成页面的动态渲染,但是 Jsp 编译运行的效率比较低。

Thymeleaf 的官方网站: http://www.thymeleaf.org

Thymeleaf 官方手册: https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html

Java 项目中使用 Thymeleaf【了解】

案例代码一:渲染静态数据

1、导入 maven 核心依赖

<dependencies>
    <!--Thymeleaf依赖-->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf</artifactId>
        <version>3.0.12.RELEASE</version>
    </dependency>

    <!--单元测试-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
    </dependency>
</dependencies>

2、测试类

// 使用模板引擎对象渲染模板中的静态数据
@Test
public void test() {
    // 创建模板引擎
    TemplateEngine templateEngine = new TemplateEngine();

    // 准备模板
    String input = "<input type='text' th:value='易烊千玺'/>";

    // 准备模板中填充的(环境上下文)内容对象
    Context context = new Context();

    // 使用模板引擎处理模板和内容并获取渲染后的结果
    String output = templateEngine.process(input, context);

    System.out.println(output);
}
案例代码二:渲染动态数据
// 使用模板引擎对象渲染模板中的动态数据
@Test
public void test2() {
    // 创建模板引擎
    TemplateEngine templateEngine = new TemplateEngine();

    // 准备模板(使用占位符)
    String input = "<input type='text' th:value='${name}'/>";

    // 准备模板中填充的(环境上下文)内容对象
    Context context = new Context();
    
    // 给内容设置参数
    context.setVariable("name", "易烊千玺");

    // 使用模板引擎处理模板和内容并获取渲染后的结果
    String output = templateEngine.process(input, context);

    System.out.println(output);
}
案例代码三:渲染 HTML 模板文件

1、html 页面

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试Thymeleaf</title>
</head>
<body>
    <input type="text" th:value="${name}">
</body>
</html>

2、测试代码

// 使用模板引擎对象渲染HTML模板中的动态数据
@Test
public void test3() {
    // 创建模板引擎
    TemplateEngine templateEngine = new TemplateEngine();
    
    // 创建模板解析器用于读取模板文件
    ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
    
    // 使用模板引擎设置模板解析器
    templateEngine.setTemplateResolver(templateResolver);

    // 准备模板中填充的(环境上下文)内容对象
    Context context = new Context();

    // 给内容设置参数
    context.setVariable("name", "易烊千玺");

    // 使用模板引擎处理模板和内容并获取渲染后的结果
    String output = templateEngine.process("index.html", context);

    System.out.println(output);
}
案例代码四:设置模板解析器的前后缀

1、在 resources 下新建 template 文件夹,并创建 main.html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试给模板解析器设置前后缀</title>
</head>
<body>
    <input type="text" th:value="${name}">
</body>
</html>

2、测试类

// 给模板解析器设置前后缀
@Test
public void test4() {
    // 创建模板引擎
    TemplateEngine templateEngine = new TemplateEngine();

    // 创建模板解析器用于读取模板文件
    ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();

    // 设置模板名称路径的前缀
    templateResolver.setPrefix("template/");

    // 设置模板名称路径的后缀
    templateResolver.setSuffix(".html");

    // 使用模板引擎设置模板解析器
    templateEngine.setTemplateResolver(templateResolver);

    // 准备模板中填充的内容对象
    Context context = new Context();

    // 给内容设置参数
    context.setVariable("name", "易烊千玺");

    // 使用模板引擎处理模板和内容并获取渲染后的结果
    String output = templateEngine.process("main", context);

    System.out.println(output);
}

SpringBoot 整合 Thymeleaf

1、pom.xml 文件添加起步依赖

<dependencies>
    <!--SpringBoot整合Thymeleaf-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!--SpringBoot整合Web项目-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!--SpringBoot整合测试-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2、创建 Controller

@Controller
@RequestMapping("thymeleaf")
public class ThymeleafController {
    @RequestMapping("test")
    public String test(Model model) {
        model.addAttribute("data", "Thymeleaf模板引擎");

        return "index";
    }
}

3、在 resources/templates 目录下新建 index.html

1、在 html 标签中添加指定命名空间

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

2、通过如下标签属性可获取 Model 中的数据

th:text="${data}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试主页</title>
</head>
<body>
    <h1 align="center" style="color: aqua;" th:text="${data}">展示数据</h1>
</body>
</html>

4、Thymeleaf 中的常见配置

spring:
  thymeleaf:
    # 开启Thymeleaf模板引擎
    enabled: true
    # 关闭Thymeleaf缓存
    cache: false
    # 设置编码集
    encoding: UTF-8
    # 设置模板类型
    mode: HTML
    # 设置访问路径的前缀
    prefix: classpath:/templates/
    # 设置访问路径的后缀
    suffix: .html
    # 处理模板前检查模板是否存在
    check-template: true
    # 是否检查模板文件的路径位置
    check-template-location: true
    servlet:
      # 设置模板内容类型
      content-type: text/html
    # 排除的视图名称
    excluded-view-names:
      # 默认模板解析器的执行顺序
    template-resolver-order:
    # 要解析的视图名称,用逗号分隔
    # view-names:

Thymeleaf 表达式

表达式分类
表达式描述案例代码
${…}变量表达式,可用于获取传入的参数<p th:text="${data}">数据</p>
*{…}选择表达式,基本没人用
#{…}消息表达式,一般用于国际化 i18n
@{…}链接网址表达式,用于替换网页中的 src、href 等的值,用的稍稍稍微多点th:href=“@{/css/home.css}”
~{…}片段表达式,可以用于引用公共的目标片段<div th:insert="~{footercopy}"></div>
变量表达式
概述

标准变量表达式用于访问容器(tomcat)上下文环境中的变量,功能和 EL 中的 ${} 相同。Thymeleaf 中的变量表达式使用 ${变量名} 的方式获取 Controller 中 model 其中的数据,也可以获取域对象中的数据。

注意:th:text=“” 是 Thymeleaf 的一个属性,用于文本的显示,语法为 ${变量名}

案例代码

1、pom.xml 导入起步依赖

<dependencies>
    <!--SpringBoot整合Thymeleaf-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--Lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

2、创建实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Car {
    private String brand;
    private String color;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String name;
    private Integer age;
    private String gender;
    private String info;
    private Car car;
}

3、创建 Controller

@Controller
@RequestMapping("test")
public class TestController {

    @RequestMapping("testStandardExpression")
    public String testStandardExpression(Model model) {
        // 设置内容为基本数据类型和字符串
        model.addAttribute("name", "易烊千玺");
        model.addAttribute("age", 21);

        // 设置内容为对象
        User user = new User(1, "易烊千玺", 21, "男", "四个字", new Car("BYD", "白色"));
        model.addAttribute("user", user);

        // 设置跳转的路径
        return "testStandardExpression";
    }
}

4、创建 index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试标准表达式</title>
</head>
<body>
    <table align="center" border="1px" width="500px">
        <caption><h1 style="color: aquamarine">基本数据类型和字符串</h1></caption>
        <tr>
            <td>姓名</td>
            <td><p th:text="${name}">姓名</p></td>
        </tr>
        <tr>
            <td>年龄</td>
            <td><p th:text="${age}">年龄</p></td>
        </tr>
    </table>

    <table align="center" border="1px" width="500px">
        <caption><h1 style="color: aquamarine">对象</h1></caption>
        <tr>
            <td>ID</td>
            <td><p th:text="${user.id}">ID</p></td>
        </tr>
        <tr>
            <td>姓名</td>
            <td><p th:text="${user.name}">姓名</p></td>
        </tr>
        <tr>
            <td>年龄</td>
            <td><p th:text="${user.age}">年龄</p></td>
        </tr>
        <tr>
            <td>性别</td>
            <td><p th:text="${user.gender}">性别</p></td>
        </tr>
        <tr>
            <td>信息</td>
            <td><p th:text="${user.info}">信息</p></td>
        </tr>
        <tr>
            <td>汽车品牌</td>
            <td><p th:text="${user.car.brand}">品牌</p></td>
        </tr>
        <tr>
            <td>汽车颜色</td>
            <td><p th:text="${user.car.color}">颜色</p></td>
        </tr>
    </table>
</body>
</html>
选择表达式【了解】
概述

选择变量表达式,也叫星号变量表达式,使用 th:object 属性来绑定对象

选择表达式首先使用 th:object 来绑定后台传来的 User 对象,然后使用 * 来代表这个对 象,后面 {} 中的值是此对象中的属性。

选择变量表达式 *{…} 是另一种类似于标准变量表达式 ${…} 表示变量的方法

选择变量表达式在执行时是在选择的对象上求解,而${…}是在上下文的变量 Model 上求解,这种写法比标准变量表达式繁琐,只需要了解即可。

案例代码

1、实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
    private Integer id;
    private String name;
    private Integer age;
}

2、Controller

@Controller
public class SelectiveController {
    @RequestMapping("selective")
    public String testSelective(Model model) {
        model.addAttribute("person", new Person(1, "易烊千玺", 21));

        return "selective";
    }
}

3、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试选择表达式</title>
</head>
<body>
    <!--通过选择变量表达式以及th标签获取对象的变量中的值-->
    <table align="center" border="1px" th:object="${person}">
        <caption><h1 style="color: blue">选择变量表达式</h1></caption>
        <tr>
            <td>ID</td>
            <td><div th:text="*{id}"></div></td>
        </tr>
        <tr>
            <td>姓名</td>
            <td><div th:text="*{name}"></div></td>
        </tr>
        <tr>
            <td>年龄</td>
            <td><div th:text="*{age}"></div></td>
        </tr>
    </table>
</body>
</html>
链接表达式
概述

主要用于链接、地址的展示,可用于

<script src="..."></script>
<link href="...">
<a href="..."></a>
<form action="..."></form>
<img src="">

可以在 URL 路径中动态获取数据,其他用法与标签跳转基本相同,可以是相对地址,也可以是绝对地址。

@{/}是相对应用根路径,其他都是相对当前路径

@{/}斜杠开头表示相对整个应用根目录,"/"表示 “/应用上下文路径”

th:href 是一个修饰符属性,将表达式结果设置为标签 href 属性的值

格式
<!--不携带参数-->
th:href="@{路径}"

<!--携带参数-->
th:href="@{路径(参数名1=${参数1},参数名2=${参数2}})}"
案例代码一:路径跳转

1、控制层

@Controller
public class LinkController {
    @RequestMapping("test/link/test")
    public String test(Model model) {
		// @{}无法获取Model中的数据
        model.addAttribute("url", "test/testStandardExpression");

        return "link";
    }

    @RequestMapping("test/link/url")
    @ResponseBody
    public String testLinkUrl() {
        return "当前路径";
    }

    @RequestMapping("test/url")
    @ResponseBody
    public String testUrl() {
        return "上级路径";
    }

    @RequestMapping("url")
    @ResponseBody
    public String test() {
        return "根路径";
    }
}

2、link.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>测试链接表达式</title>
    </head>
    <body>
        <a th:href="@{url}" >测试当前目录</a>
        <br/>
        <br/>
        <a th:href="@{/url}" >测试访问根路径</a>
        <br/>
        <br/>
        <a th:href="@{./url}" >测试当前目录</a>
        <br/>
        <br/>
        <a th:href="@{../url}" >测试上级目录</a>
        <br/>
        <br/>
        <a th:href="@{http://www.baidu.com}" >测试访问绝对路径</a>
    </body>
    <!--导入外部js文件-->
    <script th:src="@{/js/jquery-1.8.3.min.js}"></script>

</html>
案例代码二:参数传递

1、实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
    private Integer id;
    private String name;
    private Integer age;
}

2、Controller

@Controller
@RequestMapping("user")
public class UserController {
    @RequestMapping("testUrl")
    public String testUrl(Model model) {
        Person person = new Person(101, "迪丽热巴", 20);

        model.addAttribute("person", person);

        return "url";
    }

    // 测试携带参数
    @RequestMapping("getParam")
    @ResponseBody
    public Person getParam(Person person) {
        return person;
    }

    // 测试RESTful风格
    @RequestMapping("testRESTFul/{id}/{name}")
    @ResponseBody
    public String testRESTFul(@PathVariable("id") Integer id,
                              @PathVariable("name") String name) {
        return "ID:" + id + " 姓名:" + name;
    }
}

3、声明 url.html 文件

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试链接表达式传递参数</title>
</head>
<body>
<table align="center" border="1px">
    <caption><h1 style="color: blue">测试链接表达式传递参数</h1></caption>
    <tr>
        <th>ID</th>
        <th>姓名</th>
        <th>年龄</th>
        <th>操作</th>
    </tr>
    <tr>
        <td><div th:text="${person.id}"></div></td>
        <td><div th:text="${person.name}"></div></td>
        <td><div th:text="${person.age}"></div></td>
        <!--格式为@{路径(参数名1=${参数1},参数名2=${参数2}})}-->
        <td><a th:href="@{getParam(id = ${person.id}, name = ${person.name}, age = ${person.age})}">测试带参跳转</a></td>
    </tr>
    <tr>
        <td colspan="4" align="center">
            <a th:href="@{getParam(id = 1, name = '易烊千玺', age = 21)}">测试传递静态参数</a>
        </td>
    </tr>
    <tr>
        <td colspan="4" align="center">
            <a th:href="@{getParam}">测试不带参数跳转</a>
        </td>
    </tr>
    <tr>
        <td colspan="4" align="center">
            <a th:href="@{'testRESTful/' + ${person.id} + '/' + ${person.name}}">测试RESTful风格</a>
        </td>
    </tr>
</table>
</body>
</html>
消息表达式【了解】
概述

Thymeleaf 中的消息表达式是对国际化的支持,语法格式为 #{…}

i18n

国际化(Internationalization)指的是同一个网站可以支持多种不同的语言,以方便不同国家,不同语种的用户访问。

i18n(其来源是英文单词 internationalization 的首末字符i和n,18为中间的字符数)是“国际化”的简称。在资讯领域,国际化(i18n)指让产品(出版物,软件,硬件等)无需做大的改变就能够适应不同的语言和地区的需要。对程序来说,在不修改内部代码的情况下,能根据不同语言及地区显示相应的界面。 在全球化的时代,国际化尤为重要,因为产品的潜在用户可能来自世界的各个角落。通常与 i18n 相关的还有L10n(“本地化”的简称)。

案例代码

1、在 resources 下新建 i18N 文件夹并新建三个配置文件

message.properties

login=login|登录
rememberMe=rememberMe|记住我
username=username|账号
password=password|密码

message_en_US.properties

login=login
rememberMe=rememberMe
username=username
password=password

message_zh_CN.properties

login=登录
rememberMe=记住我
username=账号
password=密码

2、创建自定义国际化解析器

// 自定义国际化解析器
public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        // 从请求参数中获取语言
        String lang = request.getParameter("lang");

        // 从请求对象中获取区域对象
        Locale locale;

        // 判断是否为空
        if (lang != null && !lang.equals("")) {
            // 获取语言和地区
            String[] arr = lang.split("_");

            // 给区域对象赋值
            locale = new Locale(arr[0], arr[1]);
        } else {
            // 给区域对象赋值
            locale = new Locale("en", "US");
        }

        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

    }
}

3、自定义配置类

@Configuration
public class WebConfig {
    // 将自定义国际化解析器注入到Spring容器中
    @Bean
    public LocaleResolver localeResolver() {
        return new MyLocaleResolver();
    }
}

4、yml 配置文件

spring:
  thymeleaf:
    cache: true
  messages:
    # 配置国际化配置文件的路径
    basename: i18N/message
    encoding: UTF-8

5、Controller

@Controller
public class MessageController {
    // 测试国际化
    @RequestMapping("i18n")
    public String message() {
        return "i18n";
    }
}

6、Html 页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试消息表达式</title>
</head>
<body>
    <form>
        <table align="center">
            <caption><h1 style="color:red">测试国际化</h1></caption>
            <tr>
                <td th:text="#{username}"></td>
                <td><input type="text" name="name"/></td>
            </tr>
            <tr>
                <td th:text="#{password}"></td>
                <td><input type="password" name="password"/></td>
            </tr>
            <tr>
                <td colspan="2" style="height: 50px" align="center">
                    <input type="checkbox" th:text="#{rememberMe}">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    <button type="button" th:text="#{login}"></button>
                </td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <a href="/i18n?lang=zh_CN">中文</a>
                    <a href="/i18n?lang=en_US">English</a>
                </td>
            </tr>
        </table>
    </form>

</body>
</html>

Thymeleaf 字面量

概述

字面量:对应数据类型的合法取值,可以在 html 页面直接使用,不需要后台传递

文本
概述

文本文字只是在单引号之间指定的字符串。它们可以包含任何字符,如果字符之中没有空格,可以不加单引号。使用 “+” 连接文本。也可以使用 “|” 连接文本

案例代码

1、Controller

@Controller
public class TestController {
    // 测试文本字面量
    @RequestMapping("text")
    public String test(Model model) {
        model.addAttribute("name", "易烊千玺");
        model.addAttribute("info", "四个字");

        return "text";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试文本字面量</title>
</head>
<body>
    <p th:text="你好">文本数据</p>
    <p th:text="'你好 世界'">文本数据中带有空格必须使用单引号引起来,否则会报错</p>
    <p th:text="'你好' + '世界'">拼接字符串需要使用单引号引起来</p>
    <p th:text="'你好' + ${name}">字符串拼接变量表达式</p>
    <p th:text="|你好 ${name}|">字符串拼接变量表达式</p>
    <p th:text="|你好 ${name}${info}|">字符串拼接变量表达式</p>
    <p th:text="true">布尔值</p>
    <p th:text="123456">数值</p>
</body>
</html>
算术表达式
概述

数字文字就是∶数字,算术运算也可用:+,-,*,/ 和 %

表达式中的值可以使用 > ,< ,>= ,<= 符号进行比较。以及 == 和 != 可以用来检查是否相等。还可以使用实体引用 gt(>),lt(<),ge(>=),le(<=),not(!),eq(==), neq(!=) 等

案例代码

1、Controller

@Controller
public class TestController {

    // 测试算术字面量
    @RequestMapping("num")
    public String testNum(Model model) {
        model.addAttribute("num", "100");

        return "num";
    }
}

2、html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试算术字面量</title>
</head>
<body>
    <p th:text="100">数值</p>
    <p th:text="${num}">变量表达式获取到的数值</p>
    <p th:text="${num} + 100">数值相加</p>
    <p th:text="100 + 100 + '字符串拼接:' + 100 + 100">字符串拼接</p>
    <p th:text="100 + 100 + ':运算:' + (100 + 100)">算术运算</p>
</body>
</html>
布尔
概述

布尔是true, false。and(与),or(或),not(非)、!(非)

<th:if="布尔值"/>,布尔值为true显示标签,反之不显示<

案例代码

1、Controller

@Controller
public class TestController {
    // 测试布尔字面量
    @RequestMapping("boolean")
    public String testBoolean(Model model) {
        model.addAttribute("age", 100);
        model.addAttribute("boolean", true);

        return "boolean";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试布尔字面量</title>
</head>
<body>
    <p th:if="true">显示true</p>
    <p th:if="${boolean}">model传递过来的true</p>
    <p th:if="${age} eq 100">eq</p>
    <p th:if="${age} == 100">==</p>
    <p th:if="${age} &gt; 20 ">大于</p>
    <p th:if="${age} &lt; 200">小于</p>
    <p th:if="${boolean} and ${age} >= 100">小于等于100并且为true</p>
    <p th:if="${boolean} and ${age} <= 100">大于等于100并且为true</p>
    <p th:if="${age} != 100 or ${boolean}">不等于100或者true</p>
</body>
</html>
null
概述

null 字面量,在页面直接使用,也可以判断数据是否为null。当数据为null,标签和内容不显示。null字面量,在页面直接使用,也可以判断数据是否为null。当数据为null,标签和内容不显示。“” 字符串和 null 处理结果一样。

案例代码

1、Controller

@Controller
public class TestController {
    // 测试null字面量
    @RequestMapping("null")
    public String testNull(Model model) {
        model.addAttribute("value", null);
        model.addAttribute("string", "");

        return "null";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试null字面量</title>
</head>
<body>
    <p th:text="null">null:不显示</p>
    <p th:text="${value}">value:不显示</p>
    <p th:text="${string}">string:不显示</p>
    <p th:if="${value} eq null">null值</p>
    <p th:if="${string} eq ('')">使用括号显示空字符串</p>
    <p th:if="${string} eq ''">显示空字符串</p>
</body>
</html>
逻辑字面量
概述

逻辑运算符:and(与)、or(或)、!(非),not(非)

案例代码

1、Controller

@Controller
public class TestController {
    // 测试null字面量
    @RequestMapping("null")
    public String testNull(Model model) {
        model.addAttribute("value", null);
        model.addAttribute("string", "");

        return "null";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试逻辑字面量</title>
</head>
<body>
    <p th:if="value">显示</p>
    <p th:if="${!value}">!:不显示</p>
    <p th:if="not ${value}">not:不显示</p>
    <p th:if="not(null)">not(null):显示</p>
    <p th:if="!null">!null:显示</p>
    <p th:if="${num} > 0 and ${num} < 30">and:显示</p>
    <p th:if="${num} &gt; 0 or ${num} &lt; 20">or:显示</p>
</body>
</html>
三元运算
概述

Thymeleaf中的三元运算与Java以及JavaScript中基本一致,如 A > B ? X : Y,在 X、Y 中可以继续嵌套,只是 Thymeleaf 中需要使用括号包含起来,否则报错。

案例代码

1、Controller

@Controller
public class TestController {
    // 测试三元运算符
    @RequestMapping("ternary")
    public String testTernary(Model model) {
        model.addAttribute("name", "易烊千玺");
        model.addAttribute("age", "20");
        model.addAttribute("gender", true);

        return "ternary";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试三元表达式</title>
</head>
<body>
    <p th:text="${name} eq '易烊千玺'">true | false</p>
    <p th:text="${name} eq '易烊千玺' ? '易烊千玺' : '迪丽热巴'">易烊千玺 | 迪丽热巴</p>
    <p th:text="${name} eq '易烊千玺' ? (${age} < 20 ? '年轻' : '年老') : '迪丽热巴'">年轻 | 年老 | 迪丽热巴</p>
    <p th:text="${gender} ? '' : ''">男 | 女</p>
    <p th:text="${!gender} ? '' : ''">男 | 女</p>
</body>
</html>

Thymeleaf 常见属性

【注意】Thymeleaf 属性用法和 HTML中的标签属性基本一致,一般情况下如果需要从后台获取数据,建议使用 Thymeleaf 属性

常见属性
属性描述
th:value用于标签赋值,类似标签的 value 属性
th:action定义后台控制器的路径,类似 <form/>标签的 action 属性 ,主要结合 URL 表达式获取动态变量
th:method设置请求方法类型
th:href定义超链接,主要结合 URL 表达式,获取动态变量
th:src用于外部资源引入,比如<script>标签的 src 属性,<img>标签的 src 属性,常与 @{} 表达式结合使用,在 SpringBoot 项目的静态资源都放到 resources 的 static 目录下。 放到 static 路径下的内容,写路径时不需要写上 static
th:id类似 html 标签中的 id 属性
th:name设置名称
th:attr该属性也是用于给 HTML 中某元素的某属性赋值,好处是可以给 html 中没有定义的属性动态的赋值。
th:text用于文本的显示,该属性显示的文本在标签体中,如果是文本框,数据会在文本框外显示,要想显示在文本框内,使用 th:value
th:object用于数据对象绑定通常用于选择变量表达式
th:style设置样式
th:onclick点击事件
th:fragment定义可复用的模板片段
th:insert将被引用的模板片段插入到自己的标签体中
th:replace将被引用的模板片段替换掉自己定义的
th:include类似于 th:insert ,而不是插入片段,只插入此片段的内容
th:remove删除模板中的某些代码片段

1、pom.xml 起步依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.fc</groupId>
    <artifactId>springboot-thymeleaf-04-attribute</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-thymeleaf-04-attribute</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!--Thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--SpringBoot Web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2、声明实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String name;
    private int age;
    private String info;
}
案例代码

1、Controller 层代码

@Controller
@RequestMapping("user")
public class UserController {
    @RequestMapping("action")
    public String testAction(Model model) {
        model.addAttribute("user", new User(1, "易烊千玺", 23, "真帅"));
        return "action";
    }

    @RequestMapping("update")
    @ResponseBody
    public String update(User user) {
        return user.toString();
    }
}

2、action.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:action属性</title>
</head>
<body>
    <form th:method="post" th:action="@{update(id=${user.id})}">
        <table align="center">
            <caption><h1 style="color: red">测试Thymeleaf常见属性</h1></caption>
            <tr>
                <td>ID</td>
                <td>
                    <input type="text" th:value="${user.id}" th:id="id" disabled/>
                </td>
            </tr>

            <tr>
                <td>姓名</td>
                <td>
                    <input type="text" th:value="${user.name}" th:name="name"/>
                </td>
            </tr>

            <tr>
                <td>年龄</td>
                <td>
                    <input type="text" th:value="${user.age}" th:name="age"/>
                </td>
            </tr>

            <tr>
                <td>信息</td>
                <td>
                    <input type="text" th:value="${user.info}" th:name="info"/>
                </td>
            </tr>

            <tr>
                <td align="center" colspan="2">
                    <input type="reset" value="重置">
                    <input type="submit" value="修改">
                </td>
            </tr>
        </table>
    </form>
    <!--测试th:onclick-->
    <button th:onclick="test()">弹窗</button>
</body>
<script type="text/javascript">
    function test() {
        alert('弹弹弹');
    }
</script>
</html>
th:attr
概述

th:attr 提供了更改标签属性值的能力,可以对几乎所有的属性进行操作。但是 th:attr 使用比较少,因为他的使用比较麻烦,语法不优雅。

案例代码

1、Controller

@Controller
public class AttrController {
    @RequestMapping("attr")
    public String testAttr(Model model) {
        model.addAttribute("action", "/user/findAll");
        model.addAttribute("text", "文本");

        return "attr";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:attr</title>
</head>
<body>
    <form th:attr="action=${action}">
        <input type="text" name="text" th:attr="value=${text}">
        唱:<input type="checkbox" value="hobby" th:checked="true">
        跳:<input type="checkbox" value="hobby" th:attr="checked=true">
        <input type="submit" value="提交">
        <input  type="button" th:attr="onclick='fun()', value=${text}"/>
    </form>
</body>
<script type="text/javascript">
    function fun() {
        alert("Button On Click")
    }
</script>
</html>
th:text th:utext
概述

th:text:用来计算表达式并将结果设置标签体,会对计算结果中的特殊字符(标签)进行转义(不解析)。

th:utext:用来计算表达式并将结果设置标签体不转义(解析)

案例代码

1、Controller

@Controller
public class TextController {
    @RequestMapping("text")
    public String testText(Model model) {

        model.addAttribute("text", "<h1 style='color = red'>欢迎</h1>");

        return "text";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:text</title>
</head>
<body>
    <span th:text="${text}"></span>

    <span th:utext="${text}"></span>
</body>
</html>
th:each【重点】
描述

这个属性非常常用,比如从后台传来一个对象集合那么就可以使用此属性遍历输出,它与 JSTL 中的 <c: forEach> 类似,此属性既可以循环遍历集合,也可以循环遍历数组、 Map 以及 Iterator 接口的实现类。

属性描述
th:each用于遍历集合数组以及 Map
语法格式
th:each="obj,iterStat:${objList}"
each 参数
参数描述
obj循环体,对应迭代内容中的每一个对象,如果是 Map,则是包含了 key 和 value 的对象
iterStat循环体信息
objList遍历的内容,可以是 List,Map 和数组

【注意】循环体信息 interStat 也可以不定义,会默认采用迭代变量加上 Stat 后缀

iterStat 参数
参数描述
index当前迭代对象的下标(从 0 开始)
count当前迭代对象计数
size迭代变量中元素的总量
current当前迭代对象
first当前迭代对象是否是第一个
last当前迭代对象是否是最后一个
even当前迭代对象是否是偶数
odd当前迭代对象是否是奇数
案例代码

1、Controller

@Controller
@RequestMapping("user")
public class UserController {
    @RequestMapping("testList")
    public String testList(Model model) {
        User user1 = new User(1, "张三", 20, "真帅");
        User user2 = new User(2, "翠花", 21, "可爱");
        User user3 = new User(3, "赵四", 22, "舞王");

        List<User> list = new ArrayList<>();
        list.add(user1);
        list.add(user2);
        list.add(user3);

        model.addAttribute("list", list);

        return "each";
    }
    
    @RequestMapping("testMap")
    public String testMap(Model model) {
        User user1 = new User(1, "张三", 20, "真帅");
        User user2 = new User(2, "翠花", 21, "可爱");
        User user3 = new User(3, "赵四", 22, "舞王");

        Map<String, User> map = new HashMap<String, User>();

        map.put("1", user1);
        map.put("2", user2);
        map.put("3", user3);

        model.addAttribute("map", map);

        return "each";
    }
}

2、each.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:each遍历</title>
</head>
<body>
<table align="center">
    <caption><h1>获取List中的元素</h1></caption>
    <tr>
        <th>下标</th>
        <th>个数</th>
        <th>大小</th>
        <th>当前对象</th>
        <th>是否是第一个</th>
        <th>是否是最后一个</th>
        <th>是否是偶数</th>
        <th>是否是奇数</th>
        <th>Id</th>
        <th>姓名</th>
        <th>年龄</th>
        <th>信息</th>
    </tr>
    <tr th:each="user,status:${list}">
        <td><span th:text="${status.index}"></span></td>
        <td><span th:text="${status.count}"></span></td>
        <td><span th:text="${status.size}"></span></td>
        <td><span th:text="${status.current}"></span></td>
        <td><span th:text="${status.first}"></span></td>
        <td><span th:text="${status.last}"></span></td>
        <td><span th:text="${status.even}"></span></td>
        <td><span th:text="${status.odd}"></span></td>
        <td><span th:text="${user.id}"></span></td>
        <td><span th:text="${user.name}"></span></td>
        <td><span th:text="${user.age}"></span></td>
        <td><span th:text="${user.info}"></span></td>
    </tr>
</table>
    
    <hr color="red">

<table align="center">
    <caption><h1>遍历Map</h1></caption>
    <tr>
        <th>总数</th>
        <th>当前对象</th>
        <th></th>
        <th></th>
        <th>Id</th>
        <th>姓名</th>
        <th>年龄</th>
        <th>信息</th>
    </tr>
    <tr th:each="map, stat:${map}">
        <td><span th:text="${stat.count}"></span></td>
        <td><span th:text="${stat.current}"></span></td>
        <td><span th:text="${map.key}"></span></td>
        <td><span th:text="${map.value}"></span></td>
        <td><span th:text="${map.value.id}"></span></td>
        <td><span th:text="${map.value.name}"></span></td>
        <td><span th:text="${map.value.age}"></span></td>
        <td><span th:text="${map.value.info}"></span></td>
    </tr>
</table>
</body>
</html>
th:if th:unless

th:if 当条件满足时,显示代码片段。条件常用 boolean 表示,true 满足,反之不满足。th:unless 正好与之相反

条件判断常用表达式
表达式描述
gt大于(>)
ge大于等于(>=)
lt小于(<)
le小于等于(<=)
eq等于(==)
ne不等于(!=)
案例代码

1、Controller

@Controller
@RequestMapping("user")
public class UserController {
    @RequestMapping("if")
    public String testIf(Model model) {
        model.addAttribute("num1", 0);
        model.addAttribute("num2", 1);
        model.addAttribute("boolean", true);
        model.addAttribute("string1", "null");
        model.addAttribute("string2", "");
        model.addAttribute("string3", null);

        return "if";
    }
}

2、if.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:if</title>
</head>
<body>
    <span th:if="true">布尔true,显示</span><br/>
    <span th:if="'true'">true字符串,显示</span><br/>
    <span th:if="3 > 2">算术运算结果正确,显示</span><br/>
    <span th:if="1">非0为true,显示</span><br/>
    <span th:if="ok">ok,显示</span><br/>

    <span th:if="${num1}">0判断为false,不显示</span><br/>
    <span th:if="${num2}">1判断为true,显示</span><br/>
    <span th:if="${boolean}">true,显示</span><br/>
    <span th:if="${string1}">null字符串判断为true,显示</span><br/>
    <span th:if="${string2}">空字符串判断为true,显示</span><br/>
    <span th:if="${string3}">不显示null</span><br/>

    <span th:unless="false">false,显示</span><br/>
    <span th:unless="true">true,不显示</span><br/>
    <span th:unless="off">off,显示</span><br/>
    <span th:unless="on">on,不显示</span><br/>
    <span th:unless="null">null,显示</span><br/>
    <span th:unless="${string2}">对象,不显示</span><br/>
    <span th:unless="0">0,显示</span><br/>
    <span th:unless="1">1,不显示</span><br/>
    <span th:unless="no">no,显示</span><br/>
    <span th:unless="yes">yes,不显示</span><br/>
</body>
</html>
th:switch th:case

th:switch 和 th:case 相当于 Java SE 中的 switch 分支语句

【注意】一旦某个 case 判断值为 true,剩余的 case 默认不执行,“*” 表示默认的 case,前面的 case 都不匹配时候,执行默认的 case。相当于 switch 中的 default 。

案例代码

1、Controller

@Controller
@RequestMapping("user")
public class UserController {
    @RequestMapping("testSwitch")
    public String testSwitch(Model model) {
        User user = new User(1, "易烊千玺", 20, "真帅");

        model.addAttribute("user", user);

        return "switch";
    }
}

2、switch.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试switch</title>
</head>
<body>
    <div th:switch="${user.age}">
        <span th:case="1">1岁</span>
        <span th:case="20">20岁</span>
        <span th:case="30">30岁</span>
    </div>

    <div th:switch="${user.name}">
        <span th:case="迪丽热巴">迪丽热巴</span>
        <span th:case="古力娜扎">古力娜扎</span>
        <span th:case="*">易烊千玺</span>
    </div>
</body>
</html>
th:remove
概述

th:remove 用来删除指定的模板片段,并提供了五个参数值。

属性值描述
all删除包含标记及其所有子项。
body不删除包含标签,而是删除其所有子项。
tag删除包含标记,但不删除其子项。
all-but-first删除包含标签的所有子标签,但第一个除外。
none什么也不做,常用于动态评估
案例代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:remove</title>
</head>
<body>
    <p>测试all</p>
    <div th:remove="all">
        <h1 align="center" style="color: green">删除全部</h1>
        <h1 align="center" style="color: red">删除全部</h1>
    </div>

    <p>测试tag</p>
    <div th:remove="tag">
        <h1 align="center" style="color: green">删除包含标签不删除子项</h1>
        <h1 align="center" style="color: red">删除包含标签不删除子项</h1>
    </div>

    <p>测试body</p>
    <div th:remove="body">
        <h1 align="center" style="color: green">不删除包含标签删除子项</h1>
        <h1 align="center" style="color: red">不删除包含标签删除子项</h1>
    </div>

    <p>测试all-but-first</p>
    <div th:remove="all-but-first">
        <h1 align="center" style="color: green">删除包含标签的所有子标签,但第一个除外。</h1>
        <h1 align="center" style="color: red">删除包含标签的所有子标签,但第一个除外。</h1>
    </div>

    <p>测试none</p>
    <div th:remove="none">
        <h1 align="center" style="color: green">什么也不做</h1>
            <h1 align="center" style="color: red">什么也不做</h1>
    </div>
</body>
</html>
th:with
概述

Thymeleaf 将局部变量称为为模板的特定片段定义的变量,并且仅可用于该片段内有效。

案例代码

1、Controller

@Controller
public class WithController {
    @RequestMapping("testWith")
    public String testWith(Model model) {
        List<Student> list = new ArrayList<>();

        list.add(new Student(1, "易烊千玺", 21, new Date(), "四个字"));
        list.add(new Student(2, "迪丽热巴", 30, new Date(), "四个字"));
        model.addAttribute("list", list);

        return "with";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:with</title>
</head>
<body>
    <table align="center" border="1px">
        <tr>
            <td>Id</td>
            <td>姓名</td>
            <td>年龄</td>
            <td>生日</td>
            <td>信息</td>
        </tr>
        <tr th:with="student=${list[0]}">
            <td th:text="${student.id}"></td>
            <td th:text="${student.name}"></td>
            <td th:text="${student.age}"></td>
            <td th:text="${student.birthday}"></td>
            <td th:text="${student.info}"></td>
        </tr>
        <tr th:with="student=${list[1]}">
            <td th:text="${student.id}"></td>
            <td th:text="${student.name}"></td>
            <td th:text="${student.age}"></td>
            <td th:text="${student.birthday}"></td>
            <td th:text="${student.info}"></td>
        </tr>
    </table>

    <div th:with="str='Hello ' + 'World!'">
        <span>[[${str}]]</span>
        <span th:if="${flag}">显示</span>
        <span th:if="${num} eq 100">显示</span>
    </div>
</body>
</html>

Thymeleaf 自定义模板

概述

模板即公用资源,可以多次重复使用的内容。经常把页眉,页脚,导航栏,菜单栏声明成模板,在各个其他页面使用。模板使用必须先定义再使用。可以在当前页面定义模板,也可在其他页面中定义模板。

案例代码一:th:insert

1、Controller

@Controller
public class FragController {

    @RequestMapping("frag")
    public String test() {
        return "frag";
    }
}

2、Html

页眉

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>页眉</title>
</head>
<body>
    <div th:fragment="header">
        <h1 align="center" style="color: red; margin-top: 0">我是页眉</h1>
    </div>
</body>
</html>

页脚

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>我是页脚</title>
</head>
<body>
<div th:fragment="header">
    <h1 align="center" style="color: blue">页脚</h1>
</div>
</body>
</html>

测试

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:fragment</title>
</head>
<body>
    <div th:insert="frag/header.html::header">
        省略写法
    </div>
    <div th:insert="~{frag/header.html::header}">
        片段表达式
    </div>
    <hr/>
    <div th:insert="frag/footer.html::header">
        省略写法
    </div>
    <div th:insert="~{frag/footer.html::header}">
        片段表达式
    </div>
</body>
</html>
案例代码二:参数模板

1、argument.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>参数模板</title>
</head>
<body>
<div th:fragment="argument(address, name)">
    <h1 align="center" style="color: greenyellow" th:text="'欢迎来自' + ${address} + '' + ${name} + '登录游戏...'">我是页脚</h1>
</div>
</body>
</html>

2、测试html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:fragment</title>
</head>
<body>
    <div th:insert="frag/argument.html::argument('艾欧尼亚', '疾风剑豪')"></div>
    <div th:insert="frag/argument.html::argument(address='德玛西亚', name='迅捷斥候')"></div>
</body>
</html>
案例代码三:当前页面中定义并使用模板
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:fragment</title>
</head>
<body>
    <!--声明模板,显示一次-->
    <div th:fragment="current">
        <h1 align="center" style="color: green">当前页面中定义并使用模板</h1>
    </div>

    <!--引用模板,第二次显示-->
    <div th:insert="::current"></div>
    <!--片段表达式引用模板,第三次显示-->
    <div th:insert="~{::current}"></div>
    
    <!--声明模板,显示一次-->
    <div id="id">
        <h1 align="center" style="color: green">当前页面中定义并使用模板</h1>
    </div>

    <div th:insert="::#id"></div>
    <div th:insert="~{::#id}"></div>
</body>
</html>
案例代码四:th:replace
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:fragment</title>
</head>
<body>
    <div id="replace">
        <h1 align="center" style="color: green">测试th:replace</h1>
    </div>

    <!--直接把当前标签整体替换为模板中的内容-->
    <p th:replace="::#replace"></p>
    <p th:replace="~{::#replace}"></p>
</body>
</html>
案例代码五:th:include
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试th:fragment</title>
</head>
<body>
    <h1 id="include" align="center" style="color: green">测试th:include</h1>

    <!--把当前标签中的内容替换为模板中的内容,标签不变-->
    <p th:include="::#include"></p>
    <p th:include="~{::#include}"></p>
</body>
</html>
案例代码六:动态模板名称

1、Controller

@Controller
public class FragController {
    @RequestMapping("dynamicFrag")
    public String testDynamic(Model model) {
        model.addAttribute("frag", "header");

        return "dynamicFrag";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试动态模板</title>
</head>
<body>
    <div th:insert="frag/footer.html::${frag}">

    </div>
</body>
</html>

内联【重点】

概述

尽管标准表达式允许我们使用标签属性做几乎所有事情,但在某些情况下,我们更希望将表达式直接写入我们的 HTML 文本中,可以使用内联表达式的语法实现此功能,内联表达式内部可以使用任何表达式语法。

在 Thymeleaf 中,[[...]]或之间的表达式[(...)]被视为内联表达式[[...]]将会原样输出,[(...)]能够解析 HTML 中的标签。

案例代码一:内联表达式

1、Controller

@Controller
public class InlineController {
    @RequestMapping("inline")
    public String testInline(Model model) {
        model.addAttribute("html", "<h1 align='center' style='color: green'>易烊千玺</h1>");

        return "inline";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试内联表达式</title>
</head>
<body>
    <p>[[...]] 转义HTML --> 原样输出</p>
    <p>The message is "This is <b>[[${html}]]</b>"</p>

    <p>[(...)] 不转义HTML --> 解析HTML中的标签</p>
    <p>The message is "This is <b>[(${html})]</b>"</p>
</body>
</html>
案例代码二:内联表达式和变量表达式的比较

1、Controller

@Controller
public class InlineController {
    @RequestMapping("inline")
    public String testInline(Model model) {
        model.addAttribute("name", "易烊千玺");

        return "inline";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试内联表达式</title>
</head>
<body>
    <!--  效果相同  -->
    <p th:text="${name}"></p>
    <p>[[${name}]]</p>
</body>
</html>
案例代码三:禁用内联
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试内联表达式</title>
</head>
<body>
    <!--  禁用内联表达式  -->
    <p th:inline="none">[(${text})]</p>
    <p th:inline="none">[[${text}]]</p>
</body>
</html>
案例代码四:js 内联

1、Controller

@Controller
public class InlineController {
    @RequestMapping("inline")
    public String testInline(Model model) {
        // list
        List<Student> list = new ArrayList<>();
        list.add(new Student(1, "易烊千玺", 21, new Date(), "四个字"));
        list.add(new Student(2, "迪丽热巴", 30, new Date(), "123456"));
        model.addAttribute("list", list);

        // 数组
        Student[] array = {new Student(1, "易烊千玺", 21, new Date(), "四个字"), new Student(2, "迪丽热巴", 30, new Date(), "123456")};
        model.addAttribute("array", array);

        // map
        Map<String, Object> map = new HashMap<>();
        map.put("id", 1);
        map.put("name", "易烊千玺");
        map.put("age", 21);
        map.put("gender", "男");
        map.put("info", "四个字");
        model.addAttribute("map", map);

        // 对象
        model.addAttribute("user", new Student(1, "易烊千玺", 21, new Date(), "四个字"));

        // 字符串
        model.addAttribute("name", "易烊千玺");

        // 数值
        model.addAttribute("number", 100);

        // 布尔
        model.addAttribute("boolean", false);
        
        return "inline";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试内联表达式</title>
</head>
<body>
</body>
<script type="text/javascript" th:inline="javascript">
    // 获取字符串
    var name = [[${name}]];
    alert("字符串:" + name);

    // 获取数值
    var num = [[${number}]];
    alert("数值:" + num);

    // 获取布尔值
    var boolean = [[${boolean}]];
    alert("布尔值:" + boolean);

    // 获取到的是一个json对象
    var user = [[${user}]];
    alert("json对象:" + user.id + ":" + user.name + ":" + user.age + ":" + user.birthday + ":" + user.info);

    // 获取list集合
    var list = [[${list}]];
    for (var i = 0; i < list.length; i++) {
        var user = list[i];

        alert("list集合中的对象:" + user.id + ":" + user.name + ":" + user.age + ":" + user.birthday + ":" + user.info);
    }

    // 获取数组
    var array = [[${array}]];
    for (var i = 0; i < list.length; i++) {
        var user = array[i];
        alert("数组中的对象:" + user.id + ":" + user.name + ":" + user.age + ":" + user.birthday + ":" + user.info);
    }

    // 获取map
    var map = [[${map}]];
    for (var key in map) {
        alert("map中的键值对:" + key + ":" + map[key]);
    }
</script>
</html>
案例代码五:css 内联

1、Controller

@Controller
public class InlineController {
    @RequestMapping("inline")
    public String testInline(Model model) {
        model.addAttribute("class", "class");
        model.addAttribute("color", "red");
        model.addAttribute("align", "center");
        
        return "inline";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试内联表达式</title>
</head>
<style type="text/css" th:inline="css">
    .[[${class}]] {
        color: [[${color}]];
        text-align: [[${align}]];
    }
</style>
<body>
    <h1 class="class">测试css的内联</h1>
</body>
</html>

Thymeleaf 属性优先级

概述

HTML/XML 标准没有赋予标记中属性的写入顺序任何种类的意义,因此优先级必须在属性本身中建立机制,以确保这将按预期工作。因此,所有 Thymeleaf 属性都定义了一个数字优先级,它确定了它们在标签中的执行顺序。这种优先机制意味着如果属性位置被反转,也能得到完全相同的结果(尽管它的可读性会稍微降低)。

顺序描述属性
1片段包含th:insert th:replace
2片段迭代th:each
3条件判断th:if th:unless th:switch th:case
4局部变量定义th:object th:with
5通用属性修改th:attr th:attrprepend th:attrappend
6具体属性修改th:value th:href th:src ...
7文本(标签体修改)th:text th:utext
8片段模板th:fragment
9去除碎片th:remove
案例代码

1、Controller

// 测试属性优先级
@Controller
public class AttributePrecedenceController {
    @RequestMapping("testAttributePrecedence")
    public String test(Model model) {
        List<Student> list = new ArrayList<>();
        list.add(new Student(1, "易烊千玺", 21, new Date(), "真帅"));
        list.add(new Student(2, "迪丽热巴", 30, new Date(), "漂亮"));
        model.addAttribute("list", list);
        return "attributePrecedence";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试属性优先级</title>
</head>
<body>
    <!-- th:each -> th:if -> th:text -->
    <ul>
        <li th:each="student : ${list}" th:text="${student.name}" th:if="false">姓名</li>
    </ul>
    
    <!-- th:each -> th:object -> th:text -->
    <ul>
        <li th:each="student : ${list}" th:object="${student}" th:text="*{name}">姓名</li>
    </ul>
</body>
</html>

Thymeleaf 表达式基本对象

模板引擎提供了一组内置的对象,这些内置的对象可以直接在模板中使用,这些对象由 # 号开始引用

表达式对象描述
#ctx模板上下文对象。实现自org.thymeleaf.context.IContextorg.thymeleaf.context.IWebContext
#vars等同于#ctx,建议使用#ctx
#root等同于#ctx,建议使用#ctx
#request请求对象,就是javax.servlet.http.HttpServletRequest
#sessionsession对象,就是javax.servlet.http.HttpSession
#servletContext整个项目的上下文对象,就是javax.servlet.ServletContext
案例代码

1、Controller

@Controller
@RequestMapping("expression")
public class ExpressionController {
    @RequestMapping("test")
    public String test(HttpServletRequest request, Model model) {

        ServletContext servletContext = request.getServletContext();
        HttpSession session = request.getSession();
        session.setAttribute("data", "session");
        servletContext.setAttribute("data", "servletContext");
        model.addAttribute("data", "model");

        return "expression";
    }
}

2、expression.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试表达式对象</title>
</head>
<body>
    <!--ctx上下文对象,可以用来获取其他对象-->
    <div th:text="${#ctx.#servletContext.getAttribute('data')}"></div>
    <div th:text="${#ctx.#session.getAttribute('data')}"></div>
    <div th:text="${#ctx.#request.getAttribute('data')}"></div>

    <hr>

    <!--获取完整的请求URL-->
    <div th:text="${#request.scheme + '://' + #request.serverName + ':' + #request.serverPort + #request.contextPath + #request.servletPath + #request.queryString}"></div>
    <div th:text="${#request.requestURL}"></div>
    <div th:text="${#request.queryString}"></div>

    <hr>

    <!--session就是session对象-->
    <div th:text="${#session.getAttribute('data')}"></div>
    <div th:text="${session.data}"></div>

    <hr>

    <!--servletContext就是servletContext对象-->
    <div th:text="${#servletContext.getAttribute('data')}"></div>
    <div th:text="${application.data}"></div>
</body>
</html>

Thymeleaf 表达式实用对象【了解】

概述

模板引擎提供的一组功能性内置对象,可以在模板中直接使用这些对象提供的功能方法。工作中常使用的数据类型,如集合,时间,数值,可以使用 Thymeleaf 的提供的功能性对象来处理它们

表达式对象描述
#execInfo处理信息,提供有关Thymeleaf标准表达式中正在处理的模板的有用信息。
#messages消息,用于获取变量表达式内的外部化消息,其方式与使用#{...}语法获得消息的方式相同。
#uris在Thymeleaf标准表达式内执行URI / URL操作(尤其是转义/转义)的实用程序对象。
#conversions允许在模板的任何位置执行转换服务
#datesjava.util.Date对象的实用程序方法
#calendars类似于#dates,相当于java.util.Calendar对象
#numbers用于数字对象的实用方法
#strings字符串相关方法
#objects一般对象的实用方法
#bools用于布尔值的相关实用方法
#arrays数组的实用方法
#lists列表的实用方法
#sets集合的实用方法
#maps映射的实用方法
#aggregates骨架,用于在数组或集合上创建聚合的实用程序方法
#ids用于处理id可能重复(例如,由于迭代的结果)的属性的实用方法。

【注意】使用方法和 JDK API 基本相似,可参考官方手册:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-b-expression-utility-objects

案例代码三:uri
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试uris转义/非转义方法</title>
</head>
<body>
    <div th:with="url='https://localhost:8080/FC2021?username=易烊千玺&password=123456'">

        <!-- 转义/非转义路径后面的所有内容(包括 ?) -->
        转义:<span th:text="${#uris.escapePath(url)}"></span><br><br>
        非转义:<span th:text="${#uris.unescapePath(url)}"></span><br><br>

        <!-- 转义/非转义全部内容(包括 /) -->
        转义:<span th:text="${#uris.escapePathSegment(url)}"></span><br><br>
        非转义:<span th:text="${#uris.unescapePathSegment(url)}"></span><br><br>

        <!-- 转义/非转义请求参数部分 -->
        转义:<span th:text="${#uris.escapeQueryParam(url)}"></span><br><br>
        非转义:<span th:text="${#uris.unescapeQueryParam(url)}"></span><br><br>

    </div>
</body>
</html>
案例代码四:dates

1、Controller

@Controller
public class ExpressionUtilityObjectsController {
    @RequestMapping("dates")
    public String testDates(Model model) {
        // 日期
        model.addAttribute("date", new Date());

        // 数组
        Date[] array = {new Date(120, 0, 1, 1, 1, 1), new Date(110, 6, 3, 12, 12, 12)};
        model.addAttribute("array", array);

        // list
        List<Date> list = new ArrayList<>();
        list.add(new Date(120, 1, 1, 1, 1, 1));
        list.add(new Date(120, 2, 2, 2, 2, 2));
        model.addAttribute("list", list);

        // map
        Set<Date> set = new HashSet<>();
        set.add(new Date(120, 1, 1, 1, 1, 1));
        set.add(new Date(120, 2, 2, 2, 2, 2));
        model.addAttribute("set", set);

        return "dates";
    }
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试dates日期方法</title>
</head>
<body>
    原始日期:<p th:text="${date}"></p>
    格式化日期:<p th:text="${#dates.format(date)}"></p>
    使用指定模板格式化日期:<p th:text="${#dates.format(date, 'yyyy-MM-dd')}"></p>
    格式化数组日期:
    <ul th:each="date: ${#dates.arrayFormat(array)}">
        <li th:text="${date}"></li>
    </ul>
    格式化list日期:
    <ul th:each="date: ${#dates.listFormat(array)}">
        <li th:text="${date}"></li>
    </ul>
    格式化set日期:
    <ul th:each="date: ${#dates.listFormat(set)}">
        <li th:text="${date}"></li>
    </ul>

    获取指定日期的年月日时分秒:
    <p th:text="${#dates.year(date)} + '' + ${#dates.month(date)} + '' + ${#dates.day(date)} + '' + ${#dates.hour(date)} + '' + ${#dates.minute(date)} + '' + ${#dates.second(date)} + ''"></p>

    创建当前日期时间:
    <p th:with="now = ${#dates.createNow()}" th:text="${now}"></p>
    创建当前日期,没有时间:
    <p th:with="today = ${#dates.createToday()}" th:text="${today}"></p>
</body>
</html>
案例代码五:strings

1、Controller

@RequestMapping("strings")
public String testStrings(Model model) {
    model.addAttribute("user", new User(1, "易烊千玺", 21));
    model.addAttribute("text", "HelloWorld");

    return "strings";
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试strings</title>
</head>
<body>
    toString:对象转字符串
    <p th:text="${#strings.toString(user)}"></p>

    contains:是否包含
    <p th:text="${#strings.contains(text, 'ow')}"></p>

    contains:是否忽略大小写包含
    <p th:text="${#strings.containsIgnoreCase(text, 'ow')}"></p>

    prepend:开头拼接
    <p th:text="${#strings.prepend(text, 'Java ')}"></p>

    prepend:结尾拼接
    <p th:text="${#strings.append(text, ' Java')}"></p>

    capitalize:首字母转大写
    <p th:text="${#strings.capitalize('capitalize')}"></p>

    length:字符串长度
    <p th:text="${#strings.length('length')}"></p>

    trim:去两端空格
    <p th:text="${#strings.trim('  trim  ')}"></p>

    endsWith:以指定内容结尾
    <p th:text="${#strings.endsWith('endsWith', 'th')}"></p>

    startsWith:以指定内容开头
    <p th:text="${#strings.startsWith('startsWith', 'star')}"></p>

    indexOf:获取指定下标位置的字符
    <p th:text="${#strings.indexOf('indexOf', 3)}"></p>

    substring:截取字符串
    <p th:text="${#strings.substring('substring', 3)}"></p>

    replace:替换
    <p th:text="${#strings.replace('replace', 'ace', 'aces')}"></p>
</body>
</html>
案例代码

1、Controller

@Controller
@RequestMapping("expression")
public class ExpressionController {
    @RequestMapping("testUtilityObject")
    public String testUtilityObject(Model model) {

        List<String> list = new ArrayList<>();
        list.add("烤羊排");

        model.addAttribute("date", new Date());
        model.addAttribute("string", "SpringBoot-Thymeleaf");
        model.addAttribute("list", list);

        return "utilityObject";
    }
}

2、utilityObject.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试表达式实用对象</title>
</head>
<body>
    <div th:text="${#dates.format(date, 'yyyy-MM-dd HH:mm:ss')}"></div>
    <div th:text="${#strings.substring(string, 0, 10)}"></div>
    <div th:text="${#lists.contains(list, '烤羊排')}"></div>
</body>
</html>

【扩展】Thymeleaf 热部署

1、application.yml 配置文件中添加配置

spring:
  thymeleaf:
    # 关闭Thymeleaf缓存
    cache: false
    # 配置前/后缀(默认配置,不写也没事)
    prefix: classpath:/templates/
    suffix: .html

2、打开编辑配置,并修改运行应用程序更新策略修改为更新资源

ler

@RequestMapping("strings")
public String testStrings(Model model) {
    model.addAttribute("user", new User(1, "易烊千玺", 21));
    model.addAttribute("text", "HelloWorld");

    return "strings";
}

2、Html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试strings</title>
</head>
<body>
    toString:对象转字符串
    <p th:text="${#strings.toString(user)}"></p>

    contains:是否包含
    <p th:text="${#strings.contains(text, 'ow')}"></p>

    contains:是否忽略大小写包含
    <p th:text="${#strings.containsIgnoreCase(text, 'ow')}"></p>

    prepend:开头拼接
    <p th:text="${#strings.prepend(text, 'Java ')}"></p>

    prepend:结尾拼接
    <p th:text="${#strings.append(text, ' Java')}"></p>

    capitalize:首字母转大写
    <p th:text="${#strings.capitalize('capitalize')}"></p>

    length:字符串长度
    <p th:text="${#strings.length('length')}"></p>

    trim:去两端空格
    <p th:text="${#strings.trim('  trim  ')}"></p>

    endsWith:以指定内容结尾
    <p th:text="${#strings.endsWith('endsWith', 'th')}"></p>

    startsWith:以指定内容开头
    <p th:text="${#strings.startsWith('startsWith', 'star')}"></p>

    indexOf:获取指定下标位置的字符
    <p th:text="${#strings.indexOf('indexOf', 3)}"></p>

    substring:截取字符串
    <p th:text="${#strings.substring('substring', 3)}"></p>

    replace:替换
    <p th:text="${#strings.replace('replace', 'ace', 'aces')}"></p>
</body>
</html>
案例代码

1、Controller

@Controller
@RequestMapping("expression")
public class ExpressionController {
    @RequestMapping("testUtilityObject")
    public String testUtilityObject(Model model) {

        List<String> list = new ArrayList<>();
        list.add("烤羊排");

        model.addAttribute("date", new Date());
        model.addAttribute("string", "SpringBoot-Thymeleaf");
        model.addAttribute("list", list);

        return "utilityObject";
    }
}

2、utilityObject.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试表达式实用对象</title>
</head>
<body>
    <div th:text="${#dates.format(date, 'yyyy-MM-dd HH:mm:ss')}"></div>
    <div th:text="${#strings.substring(string, 0, 10)}"></div>
    <div th:text="${#lists.contains(list, '烤羊排')}"></div>
</body>
</html>

【扩展】Thymeleaf 热部署

1、application.yml 配置文件中添加配置

spring:
  thymeleaf:
    # 关闭Thymeleaf缓存
    cache: false
    # 配置前/后缀(默认配置,不写也没事)
    prefix: classpath:/templates/
    suffix: .html

2、打开编辑配置,并修改运行应用程序更新策略修改为更新资源
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值