thymelef
引入thymeleaf
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
从spring父文件中能看到Springboot2.7.1所使用的thymeleaf版本是3.0.15
springBoot启动的时候会自动配置
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration
从ThymeleafAutoConfiguration的源代码中我们可以得知ThymeleafProperties
中配置了Thymeleaf的规则
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING;
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
private boolean checkTemplate = true;
private boolean checkTemplateLocation = true;
private String prefix = "classpath:/templates/";
private String suffix = ".html";
private String mode = "HTML";
private Charset encoding;
private boolean cache;
我们使用html作为模板,而且默认的前缀是放在classpath:/templates/下,后缀是.html
当然这些属性我们都可以通过application.properties来修改。我们采用默认即可。
示例:
- 在templates下创建一个success.html
- 在html中引入thymeleaf的命名空间
<html lang="en" xmlns:th="http://www.thymeleaf.org">
3.创建一个Controller提供一个访问的方法
@RequestMapping("/success")
public String hello(Model model){
model.addAttribute("hello","<h1>zhangsan</h1>");
return "success";
}
- 在thymeleaf模板中取值
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <title>Title</title> </head> <body> <div th:text="${hello}"> </div> </body> </html>
th:text是纯文本,th:utext是带html模板
-
-
Thymeleaf语法
-
标准表达式语法
- 变量表达式
变量表达式即OGNL表达式或Spring EL表达式(在Spring术语中也叫model attributes)。如下所示: ${session.user.name}
它们将以HTML标签的一个属性来表示:
|
- 选择(星号)表达式
选择表达式很像变量表达式,不过它们用一个预先选择的对象来代替上下文变量容器(map)来执行,如下: *{customer.name}
被指定的object由th:object属性定义:
|
语法示例
Controller
package com.qcby.springbootthymelef.controller;
import com.qcby.springbootthymelef.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
@Controller
public class HelloController {
@RequestMapping("/success")
public String hello(HttpServletRequest req, HttpServletResponse resp, Model model){
model.addAttribute("hello","<h1>zhangsan</h1>");
User user=new User();
user.setPassword("111");
user.setUsername("zhangsan");
user.setAge(2);
user.setGender(2);
user.setScore(78);
List<User> uList = new ArrayList<>();
for (int i = 0; i < 10; i++){
User u = new User();
u.setUsername("zhangsan"+i);
u.setPassword("111"+i);
uList.add(u);
}
model.addAttribute("user", user);
model.addAttribute("uList", uList);
return "success";
}
}
html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--utext 是不会转义的,直接就是html代码,text是会转义的,${hello}是获取spring model里属性名是hello的,并把里面的内容添加到这里
th:id 用于动态设置 HTML 元素的 id 属性。
${hello.toUpperCase()} 表达式先从 Spring 模型中获取 hello 属性的值,然后调用 Java 字符串的 toUpperCase() 方法将该值转换为大写形式
-->
<div th:text="${hello}" th:id="${hello.toUpperCase()}"></div>
<!--th:value 用于动态设置 <input> 元素的 value 属性,即输入框的初始值。
${user.getUsername()} 表达式从 Spring 模型中获取名为 user 的对象,然后调用该对象的 getUsername() 方法获取用户名,并将其作为输入框的初始值。-->
<input th:value="${user.getUsername()}">
<!--用于在页面中插入一条水平线-->
<hr>
<!--th:object 用于将一个对象绑定到当前元素及其子元素上。
${user} 表达式从 Spring 模型中获取名为 user 的对象,并将其绑定到 <div> 元素上-->
<div th:object="${user}">
<!-- th:text="*{username}":
th:text 用于将指定表达式的值作为文本内容插入到当前元素中。
*{username} 是在 th:object 绑定的上下文中使用的表达式,它表示引用 th:object 绑定的 user 对象的 username 属性值,并将其作为文本内容显示在 <span> 元素中。-->
<span th:text="*{username}"></span>
</div>
<!--th:href=""用于动态设置 <a> 标签的 href 属性
th:if 是 Thymeleaf 的条件判断属性,用于根据指定的表达式结果来决定是否渲染当前元素
结果就是user的age是2就会显示超链接 -->
<a th:href="@{https://www.baidu.com/}" th:if="${user.getAge() == 2}" >年龄</a>
<!--条件表达式:${user.getAge() > 2},它会从当前上下文中获取 user 对象,并调用其 getAge() 方法获取用户的年龄,然后判断该年龄是否大于 2。
表达式1:'class1',如果用户年龄大于 2,那么 <a> 标签的 class 属性将被设置为 class1。
表达式2:'class2',如果用户年龄不大于 2(即小于等于 2),那么 <a> 标签的 class 属性将被设置为 class2。-->
<a th:class="${user.getAge() > 2}?'class1':'class2'" >年龄</a>
<!--if条件判断,获取user.score的值 根据条件判断输出结果-->
<p th:if="${user.score >= 60 and user.score < 85}">B</p>
<p th:if="${user.score < 60}">C</p>
<p th:if="${user.score > 85}">优秀</p>
<!--switch和case和java中的一样,都是选择满足条件的
th:case 指令用于定义 switch 语句中的各个 case 分支。
当 user.gender 的值等于 th:case 后面指定的值时,对应的 <p> 标签及其内容会被渲染到页面上-->
<span th:switch="${user.gender}">
<p th:case="1">男</p>
<p th:case="2">女</p>
</span>
<!--<tr th:each="a,aState:${uList}">
th:each 是 Thymeleaf 提供的循环指令,用于遍历集合或数组。
a 是循环变量,代表当前正在遍历的 uList 集合中的每个元素。在这个例子中,uList 应该是一个包含用户对象的列表,a 代表列表中的每个用户对象。
aState 是循环状态变量,它提供了一些关于当前循环状态的信息,例如当前循环的索引、是否是第一个元素、是否是最后一个元素等。
${uList} 是一个表达式,用于从当前的 Thymeleaf 上下文(通常由后端控制器传递)中获取名为 uList 的列表数据。-->
<table>
<tr th:each="a,aState:${uList}">
<td th:text="${a.username}"></td>
<td th:text="${a.password}"></td>
<td th:text="${aState.index}"></td>
</tr>
</table>
</body>
</html>
表达式支持的语法
字面(Literals)
- 文本文字(Text literals): 'one text', 'Another one!',…
- 数字文本(Number literals): 0, 34, 3.0, 12.3,…
- 布尔文本(Boolean literals): true, false
- 空(Null literal): null
- 文字标记(Literal tokens): one, sometext, main,…
文本操作(Text operations)
- 字符串连接(String concatenation): +
- 文本替换(Literal substitutions): |The name is ${name}|
算术运算(Arithmetic operations)
- 二元运算符(Binary operators): +, -, *, /, %
- 减号(单目运算符)Minus sign (unary operator): -
布尔操作(Boolean operations)
- 二元运算符(Binary operators):and, or
- 布尔否定(一元运算符)Boolean negation (unary operator):!, not
比较和等价(Comparisons and equality)
- 比较(Comparators): >, <, >=, <= (gt, lt, ge, le)
- 等值运算符(Equality operators):==, != (eq, ne)
条件运算符(Conditional operators)
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
常用的thymeleaf标签
关键字 | 功能介绍 | 案例 |
th:id | 替换id | <input th:id="'xxx' + ${collect.id}"/> |
th:text | 文本替换 | <p th:text="${collect.description}">description</p> |
th:utext | 支持html的文本替换 | <p th:utext="${htmlcontent}">conten</p> |
th:object | 替换对象 | <div th:object="${session.user}"> |
th:value | 属性赋值 | <input th:value="${user.name}" /> |
th:onclick | 点击事件 | th:οnclick="'getCollect()'" |
th:each | 属性赋值 | tr th:each="user,userStat:${users}"> |
th:if | 判断条件 | <a th:if="${userId == collect.userId}" > |
th:unless | 和th:if判断相反 | <a th:href="@{/login}" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:unless=${session.user != null}>Login</a> |
th:href | 链接地址 | <a th:href="@{/login}" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:unless=${session.user != null}>Login</a> /> |
th:switch | 多路选择 配合th:case 使用 | <div th:switch="${user.role}"> |
th:case | th:switch的一个分支 | <p th:case="'admin'">User is an administrator</p> |
th:fragment | 布局标签,定义一个代码片段,方便其它地方引用 | <div th:fragment="alert"> |
th:include | 布局标签,替换内容到引入的文件 | <head th:include="layout :: htmlhead" th:with="title='xx'"></head> /> |
th:replace | 布局标签,替换整个标签到引入的文件 | <div th:replace="fragments/header :: title"></div> |
th:selected | selected选择框 选中 | th:selected="(${xxx.id} == ${configObj.dd})" |
th:src | 图片类地址引入 | <img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" /> |
th:action | 表单提交的地址 | <form action="subscribe.html" th:action="@{/subscribe}"> |