当前位置:   article > 正文

Thymeleaf模板引擎

thymeleaf模板引擎

Thymeleaf 官网:https://www.thymeleaf.org/

​​​​​​在这里插入图片描述

(一)Thymeleaf概述

​ Thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎。类似JSP,Velocity,FreeMaker等。它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎。Thymeleaf最大的特点是能够正确显示模板页面,而不需要启动整个Web应用。
在这里插入图片描述

Thymeleaf 模板引擎的特点:

  • 动静结合:Thymeleaf 既可以直接使用浏览器打开,查看页面的静态效果,也可以通过 Web 应用程序进行访问,查看动态页面效果。
  • 开箱即用:Thymeleaf 提供了 Spring 标准方言以及一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
  • 多方言支持:它提供了 Thymeleaf 标准和 Spring 标准两种方言,可以直接套用模板实现 JSTL、 OGNL 表达式;必要时,开发人员也可以扩展和创建自定义的方言。
  • 与 SpringBoot 完美整合:SpringBoot 为 Thymeleaf 提供了的默认配置,并且还为 Thymeleaf 设置了视图解析器,因此 Thymeleaf 可以与 Spring Boot 完美整合。

(二)Thymeleaf入门

1、构建maven工程引入技术依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
	<version>2.4.3</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

2、在application.yml当中添加配置

spring:
  #开始thymeleaf设置
  thymeleaf:
    #禁用模板缓存
    cache: false
  • 1
  • 2
  • 3
  • 4
  • 5

3、编写Controller文件

package com.offcn.demo.controller;
@Controller
public class FirstThymeleafController {
/**
* 访问http://localhost:8080/first
* 将数据message填充到templates/index.html
* @param model
* @return
*/
	@GetMapping("/first")
	public String indexPage(Model model) {
		String message = "Hello, Thymeleaf!";
		model.addAttribute("message", message);
		return "index";
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

4、编写模板文件

在resources/templates下新建index.html

<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>首页</title>
</head>
<body>
	<h1 th:text="${message}"></h1>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

5、运行访问地址

http://localhost:8080/first

在这里插入图片描述

(三)Thymeleaf语法

Thymeleaf 作为一种模板引擎,它拥有自己的语法规则。Thymeleaf 语法分为以下 2 类:

  • 标准表达式语法

  • th 属性

1、标准表达式

Thymeleaf 模板引擎支持多种表达式:

  • 变量表达式:${…}
  • 选择变量表达式:*{…}
  • 链接表达式:@{…}
  • 国际化表达式:#{…}
  • 片段引用表达式:~{…}
1.1 、变量表达式:${…}
(1)获取对象的属性和方法

​ 使用变量表达式可以获取对象的属性和方法。例如,获取 person 对象的 lastName 属性,表达式形式如下:

${person.lastName}
  • 1
(2)使用内置的基本对象

​ 使用变量表达式还可以使用内置基本对象,获取内置对象的属性,调用内置对象的方法。Thymeleaf中常用的内置基本对象如下:

  • #ctx :上下文对象;
  • #vars :上下文变量;
  • #locale:上下文的语言环境;
  • #request:HttpServletRequest 对象(仅在 Web 应用中可用);
  • #response:HttpServletResponse 对象(仅在 Web 应用中可用);
  • #session:HttpSession 对象(仅在 Web 应用中可用);
  • #servletContext:ServletContext 对象(仅在 Web 应用中可用)。

我们通过以下 2 种形式,都可以获取到 session 对象中的 map 属性:

${#session.getAttribute('map')}
${session.map}
  • 1
  • 2
(3)使用内置的工具对象

​ 除了能使用内置的基本对象外,变量表达式还可以使用一些内置的工具对象。

  • strings:字符串工具对象,常用方法有:equals、equalsIgnoreCase、length、replace、startsWith、endsWith,contains 和 containsIgnoreCase 等;
  • numbers:数字工具对象,常用的方法有:formatDecimal 等;
  • bools:布尔工具对象,常用的方法有:isTrue 和 isFalse 等;
  • arrays:数组工具对象,常用的方法有:toArray、length、isEmpty、contains 和 containsAll 等;
  • lists/sets:List/Set 集合工具对象,常用的方法有:toList、size、isEmpty、contains、containsAll 和 sort 等;
  • maps:Map 集合工具对象,常用的方法有:size、isEmpty、containsKey 和 containsValue 等;
  • dates:日期工具对象,常用的方法有:format、year、month、hour 和 createNow 等。

​ 我们可以使用内置工具对象 strings 的 equals 方法,来判断字符串与对象的某个属性是否相等,代码如下。

${#strings.equals('why',name)}
  • 1
1.2、选择变量表达式:*{…}

​ 选择变量表达式与变量表达式功能基本一致,只是在变量表达式的基础上增加了与 th:object 的配合使用。

​ 当使用 th:object 存储一个对象后,我们可以在其后代中使用选择变量表达式(*{…})获取该对象中的属性,其中,“**”即代表该对象。

<div th:object="${session.user}" >
    <p th:text="*{fisrtName}">firstname</p>
</div>
  • 1
  • 2
  • 3

th:object 用于存储一个临时变量,该变量只在该标签及其后代中有效。

1.3、链接表达式:@{…}

无论是静态资源的引用,还是 form 表单的请求,凡是链接都可以用链接表达式 (@{…})。

无参请求:
<a href="http://www.baidu.com">传统写法:跳转至百度</a><br/>
<a th:href="@{http://www.baidu.com}">路径表达式:跳转至百度</a><br/>//绝对路径
<a th:href="@{/user/detail1}">跳转至:/user/detail1</a><br/>//相对路径

有参请求:
<a href="http://localhost:8080/test?username='zhangsan'">传统写法,带参数:/test,并带参数username</a><br/>
<a th:href="@{http://localhost:8080/test?username=zhangsan}">路径表达式写法,带参数:/test,并带参数username</a><br/>//绝对路径
<a th:href="@{/test?username=lisi}">相对路径,带参数</a>//相对路径
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
1.4、国际化表达式:#{…}

该表达式称之为消息表达式,消息表达式主要用于从消息源中提取消息内容实现国际化。

<p th:utext="#{home.welcome}">Hello,World!</p>
  • 1
1.5、片段引用表达式:~{…}

片段引用表达式用于在模板页面中引用其他的模板片段。

  • ~{templatename::fragmentname}
  • ~{templatename::#id}

以上语法结构说明如下:

  • templatename:模版名,Thymeleaf 会根据模版名解析完整路径:/resources/templates/templatename.html,要注意文件的路径。
  • fragmentname:片段名,Thymeleaf 通过 th:fragment 声明定义代码块,即:th:fragment=“fragmentname”
  • id:HTML 的 id 选择器,使用时要在前面加上 # 号,不支持 class 选择器。

2、th属性

属性描述
th:action定义后台控制器的路径,类似标签的 action 属性,主要结合 URL 表达式,获取动态变量
th:id类似 html 标签中的 id 属性
th:text文本替换,转义特殊字符
th:utext文本替换,不转义特殊字符
th:object在父标签选择对象,子标签使用 *{…} 选择表达式选取值。没有选择对象,那子标签使用选择表达式和 ${…} 变量表达式是一样的效果。
th:value替换 value 属性
th:name设置名称
th:src替换 HTML 中的 src 属性
th:each遍历,支持 Iterable、Map、数组等。
th:style设置样式
th:onclick点击事件
th:with局部变量赋值运算
th:if根据条件判断是否需要展示此标签
th:insert布局标签;将使用 th:fragment 属性指定的模板片段(包含标签)插入到当前标签中
th:inline内联属性;
该属性有 text,none,javascript 三种取值,

(四)使用Thymeleaf模板进行数据交互

1、Thymeleaf打印对象属性

1.1、新建一个实体bean User
package com.offcn.demo.bean;
public class User {
	private Integer id;
	private String name;
	private int age;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
1.2、新建Controller
package com.offcn.demo.controller;

import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.offcn.demo.bean.User;

@Controller
public class SecondThymeleafController {
	@GetMapping("/second")
	public String indexPage(Model model) {
		String message = "Hello, Thymeleaf!";
		User u = new User();
		u.setId(1);
		u.setName("why");
		u.setAge(18);
    
		Map<String,Object> map=new HashMap<>();
		map.put("src1","1.jpg");
		map.put("src2","2.jpg");
		model.addAttribute("message", message);
		model.addAttribute("user", u);
		model.addAttribute("src", map);
		return "index2";
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
1.3、在resource/templates下,新增模板文件index2.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>首页</title>
</head>
<body>
	<h1 th:text="${message}"></h1>
	<img th:src="${src.src1}"/>
	</br>
	<img th:src="${src.src2}"/>
	</br>
	<span th:text="${user.id}"></span>
	<span th:text="${user.name}"></span>
	<span th:text="${user.age}"></span>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
1.4、访问地址http://localhost:8080/second

在这里插入图片描述

2、Thymeleaf循环遍历集合

2.1、新建一个Controller
package com.offcn.demo.controller;
@Controller
public class ThreeThymeleafController {
	@GetMapping("/three")
	public String indexPage(Model model) {
		List<User> list=new ArrayList<User>();
		User u1 = new User();
		u1.setId(1);
		u1.setName("张三");
		u1.setAge(18);
		list.add(u1);
        
		User u2 = new User();
		u2.setId(2);
		u2.setName("李四");
		u2.setAge(28);
		list.add(u2);
        
		User u3 = new User();	
		u3.setId(3);
		u3.setName("王五");
		u3.setAge(25);
        list.add(u3);
        
        User u4 = new User();
		u4.setId(4);
		u4.setName("麻子");
		u4.setAge(888);
		list.add(u4);
        
        model.addAttribute("userList", list);
        return "index3";
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
2.2、在resource/templates下,新增模板文件index3.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>首页</title>
</head>
<body>
  <table width="200" style="text-align: center;">
	<tr>
		<th>编号</th>
		<th>姓名</th>
		<th>年龄</th>
		<th>index</th>
	</tr>
	<tr th:each="user,iterStat : ${userList}">
		<td th:text="${user.id}"></td>
		<td th:text="${user.name}"></td>
		<td th:text="${user.age}"></td>
		<td th:text="${iterStat.index}">index</td>
	</tr>
  </table>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
2.3、访问地址http://localhost:8080/three

在这里插入图片描述

3、Thymeleaf赋值、字符串拼接

3.1、新建一个Controller
package com.offcn.demo.controller;
@Controller
public class FourThymeleafController {
	@GetMapping("/four")
	public String indexPage(Model model) {
		model.addAttribute("userName", 互联网底层民工");
		model.addAttribute("href", "https://blog.csdn.net/m0_67296957");
		return "index4";
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
3.2、在resource/templates下,新增模板文件index4.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>首页</title>
</head>
<body>
<!-- 给标签赋值 th:text -->
	<h1 th:text="${userName}"></h1>
<!-- 给属性赋值 th:value、th:属性名称 -->
	<input type="text" name="names" th:value="${userName}"/>
	</br>
	<em th:size="${userName}"></em>
<!-- 字符串拼接 -->
	<span th:text="'欢迎来:'+${userName}+'学习!'"></span>
	</br>
<!-- 字符串拼接,方式2 -->
	<span th:text="|欢迎来:${userName}学习!|"></span>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
3.3、访问地址http://localhost:8080/four

在这里插入图片描述

4、Thymeleaf条件判断、选择语句

4.1、新建一个Controller
package com.offcn.demo.controller;
@Controller
public class FiveThymeleafController {
	@GetMapping("/five")
	public String indexPage(Model model) {
		model.addAttribute("flag", "yes");
		model.addAttribute("menu", "admin");
		model.addAttribute("manager", "manager");
		return "index5";
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
4.2、在resource/templates下,新增模板文件index5.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org">
	<head>
		<meta charset="UTF-8">
		<title>首页</title>
	</head>
	<body>
		<!-- th:if 条件成立就显示 -->
		<h1 th:if="${flag=='yes'}" >互联网底层民工</h1>
		<!-- th:unless 条件不成立就显示 -->
		<h1 th:unless="${flag=='no'}" >why</h1>
		<!-- switch选择语句 -->
		<div th:switch="${menu}">
			<p th:case="'admin'">User is an administrator</p>
			<p th:case="${manager}">User is a manager</p>
		</div>
	</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
4.3、访问地址http://localhost:8080/five

在这里插入图片描述

5、Thymeleaf静态资源加载

如果我们让IDE识别 .css文件,那么我们要用相对路径来引入这个文件。如果我们想要在发布后服务器能够加载这个文件,我们就必须用相对于resources或static的位置来引入静态文件。

显然,一般情况下我们不能兼顾这两个问题,只能要么在编写的时候用相对自己的路径,然后在发布的时候用相对于项目资源文件夹的路径,要么就只能放弃IDE的提示,非常尴尬。

而在Thymeleaf中,我们可很好的处理这一点。在引入资源的时候,我们可以写类似下面的代码:

<link rel="stylesheet" type="text/css" media="all" href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
  • 1

当我们在没有后台渲染的情况下,浏览器会认得href,但是不认得th:href,这样它就会选择以相对与本文件的相对路径去加载静态文件。而且我们的IDE也能识别这样的加载方式,从而给我们提示。

当我们在有后台渲染的情况下,后台会把这个标签渲染为这样:

<link rel="stylesheet" type="text/css" media="all" href="/css/gtvg.css" />
  • 1

原来的href标签会被替换成相对于项目的路径,因此服务器就能找到正确的资源,从而正确渲染。

6、Thymeleaf片段fragment定义使用

fragment类似于JSP的tag,在html中文件中,可以将多个地方出现的元素块用fragment包起来使用。

**定义fragment,**所有的fragment可以写在一个文件里面,也可以单独存在,例如:

6.1、在resource/templates下,新增模板文件footer.html
<body>
    <h1 th:fragment="copy">
		&copy; 1999-2022 Offcn.All Rights Reserved
	</h1>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5

注意: 在Springboot中,默认读取thymeleaf文件的路径是:src/main/resource/templates

6.2、编写Controller
package com.offcn.demo.controller;
@Controller
public class SixThymeleafController {
	@GetMapping("/six")
	public String indexPage(Model model) {
		return "index6";
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
6.3、 在resource/templates下,新增视图文件index6.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org">
	<head>
		<meta charset="UTF-8">
		<title>首页</title>
	</head>
	<body>
		<!-- 把片段的内容插入到当前位置 -->
		<div style="color: #82ff6c" th:insert="~{footer :: copy}"></div>
		</br>
		<!-- 使用片段的内容替换当前标签 -->
		<div style="color: #82ff6c" th:replace="~{footer :: copy}"></div>
		</br>
		<!-- 保留自己的主标签,不要片段的主标签 -->
		<div style="color: #82ff6c" th:include="~{footer :: copy}"></div>
	</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

th:insert:保留自己的主标签,保留th:fragment的主标签。

th:replace:不要自己的主标签,保留th:fragment的主标签。

th:include:保留自己的主标签,不要th:fragment的主标签。

6.4、访问地址http://localhost:8080/six运行

在这里插入图片描述

7、Thymeleaf表达式内置对象使用

7.1、常见内置工具:

#dates:与java.util.Data对象的方法对应,格式化、日期组件抽取等等

#numbers:格式化数字对象的工具方法

#strings:与java.lang.String对应的工具方法

7.2、编写Controller
package com.offcn.demo.controller;
@Controller
public class SevenThymeleafController {
	@GetMapping("/seven")
	public String indexPage(Model model) {
		//日期时间
		Date date = new Date();
		model.addAttribute("date", date);
		//小数的金额
		double price=128.5678D;
		model.addAttribute("price", price);
		//定义大文本数据
		String str="Thymeleaf是Web和独立环境的现代服务器端Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚至纯文本。\r\n" +
		"Thymeleaf的主要目标是提供一种优雅和高度可维护的创建模板的方式。为了实现这一点,它建立在自然模板的概念上,将其逻辑注入到模板文件中,不会影响模板被用作设计原型。这改善了设计的沟通,弥补了设计和开发团队之间的差距。\r\n" +
		"Thymeleaf也从一开始就设计了Web标准 - 特别是HTML5 - 允许您创建完全验证的模板,如果这是您需要的\r\n" ;
		model.addAttribute("strText", str);

  	  //定义字符串
  	    String str2="JAVA-why";
		model.addAttribute("str2", str2);
		return "index7";
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
7.3、在resource/templates下,新增视图文件index7.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>首页</title>
</head>
<body>
时间:<span th:text="${#dates.format(date,'yyyy-MM-dd HH:mm:ss')}">4564546</span>
</br>
金额:<span th:text="'¥'+${#numbers.formatDecimal(price, 1, 2)}">180</span> </br>
<!-- # 这里的含义是 如果 atc.text 这个变量多余60个字符,后面显示... -->
<p th:text="${#strings.abbreviate(strText,60)}">内容内容内容</p>

<!-- 判断字符串是否为空 -->
<span th:if="${!#strings.isEmpty(str2)}">字符串str2不为空</span></br>
<!-- 截取字符串,指定长度 -->
<span th:text="${#strings.substring(str2,0,4)}">字符串str2的值</span>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
7.4、运行访问地址http://localhost:8080/seven

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码创新者/article/detail/62698
推荐阅读
相关标签
  

闽ICP备14008679号