1、第一步:在Maven中引入Thymeleaf的依赖,加入以下依赖配置即可:
<!--springboot集成Thymeleaf的起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2.第二步:在Spring boot的核心配置文件application.properties中对Thymeleaf进行配置
#开发阶段,建议关闭thymeleaf的缓存
spring.thymeleaf.cache=false
3、第三步:写一个Controller去映射到模板页面(和SpringMVC基本一致),比如
@RequestMapping("/boot/index")
public String index (HttpSession session, Model model) {
model.addAttribute("data", "Spring boot集成 Thymeleaf!");
//return 中就是你页面的名字(不带.html后缀)
return "index";
}
4、第四步:在src/main/resources的templates下新建一个index.html页面用于展示数据:HTML页面的<html>元素中加入以下属性:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Spring Boot集成Thymeleaf</title>
</head>
<body th:inline="text">
<p th:text="${data}">
</p>
</body>
</html>
启动项目,访问/boot/index这个方法,即可在页面显示出data的内容
Springboot使用thymeleaf作为视图展示,约定将模板文件放置在src/main/resource/templates目录下,静态资源放置在src/main/resource/static目录下
Thymeleaf 的标准表达式主要有如下几类:
1、标准变量表达式语法:${...}变量表达式用于访问容器(tomcat)上下文环境中的变量,功能和JSTL 中的${} 相同;Thymeleaf 中的变量表达式使用${变量名} 的方式获取其中的数据比如在Spring mvc 的Controllar中使用model.addAttribute向前端传输数据,代码如下
@RequestMapping("/boot/index")
public String index (HttpSession session, Model model) {
User user = new User();
user.setId(1);
user.setNick("baiyang");
user.setPhone("13000000000");
user.setEmail("001@163.com");
user.setAddress("fujian");
model.addAttribute("user", user);
//return 中就是你页面的名字(不带.html后缀)
return "index";
}
前端接收代码:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Spring Boot集成Thymeleaf</title>
</head>
<body th:inline="text">
展示user对象的数据(标准标量表达式)<br/>
<p>
<span th:text="${user.id}"> </span>
<span th:text="${user.nick}"> </span>
<span th:text="${user.phone}"> </span>
<span th:text="${user.email}"> </span>
<span th:text="${user.address}"> </span>
</p>
</body>
</html>
其中,th:text="" 是Thymeleaf的一个属性,用于文本的显示
2、URL表达式
语法:@{...}
URL表 达 式 可 用 于<script src="...">、<link href="...">、<a href="...">、<form action="...">
等
2.1、绝对URL,比如:
<a th:href="@{'https://www.java3.cn/article/43.html?id='+${user.id}}">查看</a>
2.2、相对URL,相对于页面,比如
<a th:href="@{'user/info?id='+${user.id}}">查看</a>
2.3、相对URL,相对于项目上下文,比如
a th:href="@{'/user/info?id='+${user.id}}">查看</a>
(项目的上下文名会被自动添加)
以下为thymeleaf的常见属性:
th:action
定义后台控制器的路径,类似<form>标签的action属性,比如:
如果你的属性中要显示后台的动态变量数据,那么你不得不使用th:开头的属性
<form id="login" th:action="@{/login}" ></form>
th:method
设置请求方法,比如:
如果你的属性中不需要显示动态数据,而是显示一个写死的静态值,那么你可以不使用th:开头的属性
<form id="login" th:action="@{/login}" th:method="post"></form>
th:href
定义超链接,比如
<a class="login" th:href="@{/login}">登录</a>
th:src
用于外部资源引入,比如<script>标签的src属性,<img>标签的src属性,常与@{}表达式结合使用;
<script th:src="@{/js/jquery-2.3.min.js}"></script>
<img th:src="@{/image/logo.jpg}"/>
th:id
类似html标签中的id属性,比如
<span th:id="${id}">111</span>
th:name
设置表单名称,比如
<input th:type="text" th:id="userName" th:name="userName">
th:value
类似html标签中的value属性,能对某元素的value属性进行赋值,比如
<input type="hidden" id="userId" name="userId" th:value="${userId}">
th:attr
该属性也是用于给HTML中某元素的某属性赋值,但该方式写法不够优雅,比如上面的例子可以写成如下形式:
<input type="hidden" id="userId" name="userId" th:attr="value=${userId}">
th:text
用于文本的显示,比如
<input type="text" id="realName" name="reaName" th:text="${realName}">
th:each
这个属性非常常用,比如从后台传来一个对象集合那么就可以使用此属性遍历输出,它与JSTL中的<c: forEach>类似,此属性既可以循环遍历集合,也可以循环遍历数组及Map,比如
循环展示List集合
<p>
<span th:each="user,interStat : ${userList}">
<span th:text="${userStat.count}"> </span>
<span th:text="${user.id}"> </span>
<span th:text="${user.nick}"> </span>
<span th:text="${user.phone}"> </span>
<span th:text="${user.email}"> </span>
<span th:text="${user.address}"> </span>
<br/>
</span>
</p>
以上代码解读如下:th:each="user, iterStat : ${userlist}"
中的${userList} 是后台传来的集合,如下
@RequestMapping("/boot/index")
public String index (HttpSession session, Model model) {
List<User> userList = new ArrayList<>();
for (int i=0; i<5; i++) {
User u = new User();
u.setId(1);
u.setNick("wenleme");
u.setPhone("13500000000");
u.setEmail("111@163.com");
u.setAddress("mohe");
userList.add(u);
}
model.addAttribute("userList", userList);
//return 中就是你页面的名字(不带.html后缀)
return "index";
}
user是${userList} 中的一个数据,
interStat 是${userList} 循环体的信息,其中user及iterStat自己可以随便写;
interStat是循环体的信息,通过该变量可以获取如下信息:
index、size、count、even、odd、first、last,其含义如下:
index: 当前迭代对象的index(从0开始计算)
count: 当前迭代对象的个数(从1开始计算)
size: 被迭代对象的大小
current: 当前迭代变量
even/odd: 布尔值,当前循环是否是偶数/奇数(从0开始计算)
first: 布尔值,当前循环是否是第一个
last: 布尔值,当前循环是否是最后一个
注意:循环体信息interStat也可以不定义,则默认采用迭代变量加上Stat后缀,即userStat
例如:
<p>
<span th:each="user : ${userList}">
<span th:text="${userStat.count}"> </span>
<span th:text="${user.id}"> </span>
<br/>
</span>
</p>
Map类型的循环
后端:
@RequestMapping("/boot/index")
public String index (Model model) {
Map<String, User> userMap = new HashMap<String, User>();
for (int i=0; i<5; i++) {
User u = new User();
u.setId(1);
u.setNick("wangwu");
u.setPhone("13000000000");
u.setEmail("111@163.com");
u.setAddress("heilongjiang");
userMap.put(String.valueOf(i), u);
}
model.addAttribute("userMap", userMap);
//return 中就是你页面的名字(不带.html后缀)
return "index";
}
循环遍历map集合
<p>
<span th:each="keyValue : ${userMap}">
<span th:text="${keyValue.key}"></span>
<span th:text="${keyValue.value.id}"></span>
<span th:text="${keyValue.value.nick}"></span>
<span th:text="${keyValue.value.phone}"></span>
<span th:text="${keyValue.value.email}"></span>
<span th:text="${keyValue.value.address}"></span>
<br/>
</span>
</p>
${myMapVal.key} 是获取map中的key,${myMapVal.value} 是获取map中的value
复杂Map遍历(循环展示复合集合)
后端传来的数据如下:
@RequestMapping("/boot/index")
public String index (HttpSession session, Model model) {
List<User> userList = new ArrayList<>();
Map<String, Object> map = new HashMap<String, Object>();
for (int i=0; i<5; i++) {
User u = new User();
u.setId(1);
u.setNick("zhangsan");
u.setPhone("13500000000");
u.setEmail("111@163.com");
u.setAddress("mohe");
userList.add(u);
}
map.put("1", userList);
List<User> userList2 = new ArrayList<>();
for (int i=0; i<5; i++) {
User u = new User();
u.setId(i);
u.setNick("lisi");
u.setPhone("13600000000");
u.setEmail("222@163.com");
u.setAddress("heilongjiang");
userList2.add(u);
}
map.put("2", userList2);
model.addAttribute("map", map);
//return 中就是你页面的名字(不带.html后缀)
return "index";
}
前端遍历
<p>
<span th:each="keyValue : ${map}">
key:<br/>
<span th:text="${keyValue.key}"></span>
<br/>
value:<br/>
<span th:each="user : ${keyValue.value}">
<span th:text="${user.id}"> </span>
<span th:text="${user.nick}"> </span>
<span th:text="${user.phone}"> </span>
<span th:text="${user.email}"> </span>
<span th:text="${user.address}"> </span>
<br/>
</span>
</span>
</p>
数组类型的循环:
<p>
<span th:each="user : ${userArray}">
<span th:text="${user.id}"> </span>
<span th:text="${user.nick}"> </span>
<span th:text="${user.phone}"> </span>
<span th:text="${user.email}"> </span>
<span th:text="${user.address}"> </span>
<br/>
</span>
</p>
数组的遍历和List集合的遍历差不多
th:if
条件判断,比如后台传来一个变量,判断该变量的值,1为男,2为女:
<span th:if="${sex == 1}">
性别:男
</span>
<span th:if="${sex == 2}">
性别:女
</span>
th:unless
th:unless是th:if的一个相反操作,上面的例子可以改写为
<span th:unless="${sex == 1}">
性别:男
</span>
<span th:unless="${sex == 2}">
性别:女
</span>
th:switch/th:case
switch,case判断语句,比如
<span th:switch="${sex}">
<span th:case="1">男</span>
<span th:case="2">女</span>
<span th:case="*">----</span>
</span>
一旦某个case判断值为true,剩余的case则都当做false,“*”表示默认的case,前面的case都不匹配时候,执行默认的case
th:onclick
点击事件,th:onclick="'getCollect()'"
th:style
设置样式,th:style="'display:none;'"
th:inline
内联文本、内联脚本
th:inline 有三个取值类型(text, javascript 和none)
该属性使用内联表达式[[...]]展示变量数据,比如:
<span th:inline="text">Hello, [[${user.nick}]]</span>
等同于
<span>Hello, <span th:text="${user.nick}"></span></span>
可以脱离h5标签使用
th:inline写在任何父标签都可以,比如如下也是可以的
<body th:inline="text">
...
<span>[[${user.nick}]]</span>
...
</body>
内联脚本
可以在js里面取后台传的值
<script th:type="'text/javascript'" th:inline="javascript">
function myClick() {
//有了内联脚本,就可以直接在javascript代码中获取后台的动态变量数据
var phone = [[${user.phone}]];
alert("恭喜 " +phone+ ",抽奖成功!");
}
</script>
文本字面量
用单引号'...'包围的字符串为文本字面量,比如:
<a th:href="@{'api/getUser?id=' + ${user.id}}">修改</a>
数字字面量
<p>今年是<span th:text="2017">1949</span>年</p>
<p>20年后, 将是<span th:text="2017 + 20">1969</span>年</p>
布尔字面量
true和false
<p th:if="${isFlag == true}">执行操作</p>
null字面量
<p th:if="${userlist == null}">userlist为空</p>
<p th:if="${userlist != null}">userlist不为空</p>
一种是字面量拼接:
<span th:text="'当前是第'+${sex}+'页,共'+${sex}+'页'"></span>
另一种更优雅的方式,使用“|”减少了字符串的拼接:
<span th:text="|当前是第${sex}页,共${sex}页|"></span>
<span th:text="${sex eq 1} ? '男' : '女'">未知</span>
<span th:style="${sex eq 1} ? 'color:blue;' : 'color:red;'">颜色的展示</span>
算术运算:+ , -, * , / , %
关系比较: > , < , >= , <= ( gt , lt , ge , le )
相等判断:== , != ( eq , ne )
8.1、模板引擎提供了一组内置的对象,这些内置的对象可以直接在模板中使用,这些对象由#号开始引用:
8.2、官方手册:http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
#request:
相当于HttpServletRequest 对象,这是3.x版本,若是2.x版本使用#httpServletRequest;
${#request.getContextPath()}
${#request.getAttribute("phone")}
#session:
相当于HttpSession 对象,这是3.x版本,若是2.x版本使用#httpSession;
需要在后台controller中设置了session
如:
@RequestMapping("/boot/index")
public String index (HttpSession session, Model model) {
//return 中就是你页面的名字(不带.html后缀)
return "index";
}
${#session.id}
${#session.lastAccessedTime}
9.1、模板引擎提供的一组功能性内置对象,可以在模板中直接使用这些对象提供的功能方法:
9.2、 工作中常使用的数据类型, 如集合,时间,数值,可以使用thymeleaf的提供的功能性对象来处理它们;
9.3、内置功能对象前都需要加#号,内置对象一般都以s结尾;
9.4、官方手册:http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
#dates: java.util.Date对象的实用方法,
<span th:text="${#dates.format(curDate, 'yyyy-MM-dd HH:mm:ss')}"></span>
#calendars: 和dates类似, 但是java.util.Calendar 对象;
#numbers: 格式化数字对象的实用方法;
#strings: 字符串对象的实用方法:contains, startsWith, prepending/appending等;
<span th:text="${#strings.substring(nowDateStr, 0, 10)}"></span>
#objects: 对objects操作的实用方法;
#bools: 对布尔值求值的实用方法;
#arrays: 数组的实用方法;
#lists: list的实用方法,比如
<span th:text="${#lists.size(datas)}"></span>
#sets: set的实用方法;
#maps: map的实用方法;
#aggregates: 对数组或集合创建聚合的实用方法;
<span th:text="${#aggregates.avg(intArray)}"></span>