目录
(3)算术运算(Arithmetic operations)
(5)比较和等价(Comparisons and equality)
(6)条件运算符(Conditional operators)
前端常见的模板引擎有:JSP、Velocity、Freemarker、Thymeleaf
Spring Boot推荐使用Thymeleaf作为默认的模板引擎,它提供了简洁的语法和强大的功能。
接下来我们一起学习thymeleaf基础语法。
1. 引入thymeleaf
在pom.xml中引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
从spring父文件中能看到Springboot2.5.6所使用的thymeleaf版本是3.0.12
springBoot启动的时候会自动配置
从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;
private Integer templateResolverOrder;
private String[] viewNames;
private String[] excludedViewNames;
private boolean enableSpringElCompiler;
private boolean renderHiddenMarkersBeforeCheckboxes;
private boolean enabled;
private final ThymeleafProperties.Servlet servlet;
private final ThymeleafProperties.Reactive reactive;
...
}
我们使用html作为模板,而且默认的前缀是放在classpath:/templates/下,后缀是.html
当然这些属性我们都可以通过application.properties来修改。我们采用默认即可。
示例:
(1)在templates下创建一个success.html
(2)在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";
}
(4)在thymeleaf模板中取值
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:text="${hello}"></div>
</body>
</html>
在浏览器中输入:http://localhost:8080/success
2. thymeleaf语法
2.1 标准表达式语法
Thymeleaf 提供了四种标准表达式语法,用于在模板中执行不同的任务。
(1)变量表达式
变量表达式用于访问在模型中定义的属性。它们可以使用 OGNL 表达式或 Spring Expression Language (SpEL)。
语法示例:
<span th:text="${session.user.name}">
这将显示会话中用户对象的 name
属性。
(2)选择(星号)表达式
选择表达式与变量表达式类似,但它们使用一个预先选择的对象来代替上下文变量容器。这个对象由 th:object
属性定义。
语法示例:
<div th:object="${book}">
<span th:text="*{title}">...</span>
</div>
这里,th:object
定义了 book
作为当前对象,然后 *{title}
访问 book
对象的 title
属性。
(3)文字国际化表达式
文字国际化表达式允许我们从一个外部文件获取区域文字信息(.properties),用Key索引Value,还可以提供一组参数(可选).。
语法示例:
#{main.title}
这将从国际化资源文件中获取键为 main.title
的文本。
(4)URL表达式
URL表达式用于在URL中添加上下文或会话信息,这个过程通常被称为URL重写。它不需要指定项目名称。
语法示例:
@{/order/list}
这将生成指向 /order/list
的URL。
带参数的URL示例:
@{/order/details(id=${orderId})}
这将生成一个包含 orderId
参数的URL。
完整示例
<form th:action="@{/createOrder}">
<a href="main.html" rel="external nofollow" th:href="@{/main}" rel="external nofollow">Home</a>
</form>
在这个示例中,表单的 action
属性被设置为 /createOrder
,而链接的 href
属性被设置为 /main
,同时保持了原有的 rel
属性。
2.2 表达式支持的语法
(1)字面量(Literals)
字面量是直接在模板中使用的固定值。
- 文本文字:
'one text'
,'Another one!'
- 数字文本:
0
,34
,3.0
,12.3
- 布尔文本:
true
,false
- 空值:
null
- 文字标记:
one
,sometext
,main
(2)文本操作(Text operations)
文本操作用于处理和组合文本。
字符串连接:使用
+
运算符连接字符串,例如:${'Hello ' + name + '!'}
。文本替换:使用
${...}
语法替换文本,例如:|The name is ${name}|
。
(3)算术运算(Arithmetic operations)
算术运算用于执行数学计算。
- 二元运算符:
+
,-
,*
,/
,%
,例如:${2 + 2}
或${10 / 2}
。 - 单目运算符:
-
用于取反,例如:${-(2 + 2)}
。
(4)布尔操作(Boolean operations)
布尔操作用于处理逻辑值。
- 二元运算符:
and
,or
,例如:${user != null and user.enabled}
或${user != null or user.disabled}
。 - 一元运算符:
!
,not
,例如:${!user.enabled}
或${not user.enabled}
。
(5)比较和等价(Comparisons and equality)
比较和等价运算符用于比较值。
- 比较运算符:
>
,<
,>=
,<=
(在Thymeleaf中分别表示为gt
,lt
,ge
,le
),例如:${age > 18}
。 - 等值运算符:
==
,!=
(在Thymeleaf中分别表示为eq
,ne
),例如:${user.name == 'admin'}
。
(6)条件运算符(Conditional operators)
条件运算符用于基于条件执行不同的操作。
- If-then:
(if) ? (then)
,例如:${user != null ? user.name : 'Anonymous'}
。 - If-then-else:
(if) ? (then) : (else)
,例如:${user != null ? user.name : 'Guest'}
。 - Default:
(value) ?: (defaultvalue)
,这是三元运算符的简写形式,例如:${user.name ?: 'Guest'}
。
2.3 常用的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}"> |
标签测试
模板:
<!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}" th:id="${hello.toUpperCase()}">xxxx</div>
<input th:value="${user.getUsername()}">
<hr>
<div th:object="${user}">
<span th:text="*{username}"></span>
</div>
<a th:href="@{/toTest1}" th:if="${user.getAge() == 2}" >链接</a>
<a th:class="${user.getAge() > 2}?'class1':'class2'" >年龄</a>
<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>
<span th:switch="${user.gender}">
<p th:case="1">男</p>
<p th:case="2">女</p>
</span>
<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>
@RequestMapping("/test")
public String hello(HttpServletRequest req, HttpSession httpSession, Model model){
model.addAttribute("hello","<h1>renliang</h1>");
User user = new User();
user.setPassword("111");
user.setUsername("小美");
user.setAge(2);
user.setScore(78);
user.setGender(2);
List<User> uList = new ArrayList<>();
for (int i = 0; i < 10; i++){
User u = new User();
u.setUsername("小美"+i);
u.setPassword("111"+i);
uList.add(u);
}
model.addAttribute("user", user);
model.addAttribute("uList", uList);
return "test";
}
@RequestMapping("/toTest1")
public String toTest1(){
return "test1";
}