认识Thymeleaf
Thymeleaf 是一个流行的模板引擎,该模板引擎采用 Java 语言开发
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
springboot继承Thymeleaf
- 需要添加依赖
<!--SpringBoot 集成 Thymeleaf 的起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
- 在核心配置文件Thymeleaf进行配置
#thymeleaf 页面的缓存开关,默认 true 开启缓存
#建议在开发阶段关闭 thymeleaf 页面缓存,目的实时看到页面
spring.thymeleaf.cache=false
#thymeleaf 模版前缀,默认可以不写
spring.thymeleaf.prefix=classpath:/templates/
#thymeleaf 模版后缀,默认可以不写
spring.thymeleaf.suffix=.html
- controller 层基本不变,举个例子
@Controller
public class ThymeleafController {
@RequestMapping(value = "/thymeleaf/index")
public String index(Model model) {
model.addAttribute("data","SpringBoot 成功集成 Thymeleaf 模版!");
return "index";
}
}
- 接收页面HTML有变化,HTML 页面的
<html>
元素中加入以下属性:
<html xmlns:th="http://www.thymeleaf.org">
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>SpringBoot 集成 Thymeleaf</title>
</head>
<body >
<!--Thymeleaf 前端框架以 Html 为载体-->
<span th:text="${data}"></span>
<span th:text="${data}"></span>
<p th:text="${data}"></p>
<div th:text="${data}"></div>
</body>
</html>
前台页面取值都采用 th:属性名 的形式,取值使用 ${request域中的key} 的形式 。th:text 取得值是放在标签体中
5. 运行结果
Thymeleaf表达式
标准变量表达式
${ ... }
Thymeleaf 中的变量表达式使用 ${变量名} 的方式获取 Controller 中 model 其中的数据。功能和 EL 中的 ${} 相同,读取的是request域中对象的值
@RequestMapping(value = "/thymeleaf/user")
public String user(Model model) {
User user = new User();
user.setId(1);
user.setName("张三");
user.setPhone("13700000000");
user.setAddress("北京市亦庄经济开发区");
model.addAttribute("user",user);
return "user";
}
<body>
<h2>展示 User 用户信息:</h2>
用户编号:<span th:text="${user.id}"></span><br/>
用户姓名:<span th:text="${user.name}"></span><br/>
用户手机号:<span th:text="${user.phone}"></span><br/>
用户地址:<span th:text="${user.address}"></span><br/>
</body>
选择变量表达式(了解)
*{...}
也叫星号变量表达式,选择表达式首先使用 th:object 来绑定后台传来的 User 对象,然后使用 * 来代表这个对象,后面 {} 中的值是此对象中的属性。读取的是request域中对象的值
<h2>展示 User 用户信息(星号表达式,仅在 div 范围内有效):</h2>
<div th:object="${user}">
用户编号:<span th:text="*{id}"></span><br/>
用户姓名:<span th:text="*{name}"></span><br/>
用户手机号:<span th:text="*{phone}"></span><br/>
用户地址:<span th:text="*{address}"></span><br/>
</div>
URl表达式
@{...}
主要用于链接、地址的展示,可用于<script src="...">
、<link href="...">
、<a href="...">
、<form action="...">
、<img src="...">
等,可以在 URL 路径中动态获取数据
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>URL 路径表达式 -> @{}</title>
</head>
<body>
<h1>URL 路径表达式:@{...}</h1>
<h2>绝对路径(没有参数)</h2>
<a th:href="@{http://localhost:8080/thymeleaf/info}">查看:绝对路径</a>
<h2>绝对路径(路径中有参数)</h2>
<a th:href="@{'http://localhost:8080/thymeleaf/user/info?id=' +
${user.id}}">查看用户信息:绝对路径(带参数)</a>
<h2 style="color: red">实际开发推荐使用:相对路径(没有参数)</h2>
<a th:href="@{/thymeleaf/info}">查看:相对路径</a>
<h2 style="color: red">实际开发推荐使用:相对路径(路径中有参数)</h2>
<a th:href="@{'/thymeleaf/user/info?id=' + ${user.id}}">查看用户信息:相对路径(带参数)</a>
<a th:href="@{/thymeleaf/info(id=${user.id})}">推荐使用:优雅的带参数路径写法</a>
<a th:href="@{/thymeleaf/info(id=${user.id},name=${user.name})">推荐使用:传递多个参数</a>
</body>
</html>
开发常用方式,相对路径,前面使用 “/” ,自动添加路径上下文根
<h2 style="color: red">实际开发推荐使用:相对路径(没有参数)</h2>
<a th:href="@{/thymeleaf/info}">查看:相对路径</a>
<h2 style="color: red">实际开发推荐使用:相对路径(路径中有参数)</h2>
<a th:href="@{'/thymeleaf/user/info?id=' + ${user.id}}">查看用户信息:相对路径(带参数)</a>
<a th:href="@{/thymeleaf/info(id=${user.id})}">推荐使用:优雅的带参数路径写法</a>
<a th:href="@{/thymeleaf/info(id=${user.id},name=${user.name})">推荐使用:传递多个参数</a>
Thymeleaf常见属性
th:action
<h1>th:action 属性的使用</h1>
<h2>请求路径中需要动态获取变量数据时,必须添加 th 前缀</h2>
<form th:action="@{'/user/login?id='+${user.id}}"></form>
<h2>以下两种方式获取不到用户 id</h2>
<form action="'/user/login?id='+${user.id}"></form>
<form action="/user/login"+${user.id}></form>
为什么后两个 中${user.id}
获取不到数据? 获取不到数据?
因为我们 Thymeleaf 是以 html 为载体的,所以 html 不会认识${} 语法。我们请求的流程是,发送请求给服务器,服务器接收请求后,处理请求,跳转到指定的 静态html 页面,在服务器端,Thymeleaf , 模板引擎会按照它的语法, 对动态数据进行处理, 所以是 如果要是 th 开头,模板引擎能够识别,会在服务器端进行处理,获取数据;如果没有以 th 开头,那么 Thymeleaf 模板引擎不会处理,直接返回给客户端了
th:method
设置请求方法
<form id="login" th:action="@{/login}" th:method="post">......</form>
th:href
<a href="http://www.baidu.com">超链接百度</a><br/> <a th:href="'http://www.baidu.com?id=' + ${user.id}">th:href 链接</a>
th:src
SpringBoot 项目的静态资源都放到 resources 的 的 static 目录下。放到 static 路径下的内容,写路径时不需要写上 static
<!--以下方式无法引入 js-->
<script src="/static/js/jquery-1.7.2.min.js"></script>
<!--该方法是常用方法-->
<script type="text/javascript" th:src="@{/js/jquery-1.7.2.min.js}"></script>
th:id
<span th:id="${hello}">aaa</span>
th:name
<input th:type="text" th:id="userName" th:name="userName">
th:value
<input type="hidden" id="userId" name="userId" th:value="${userId}">
th:attr
可以给 html 中没有定义的属性动态的赋值。
<span zhangsan="${user.name}"></span>
<!--通过 th:attr 对自定义的属性赋值-->
<span th:attr="zhangsan=${user.name}"></span>
th:text
用于文本的显示,该属性显示的文本在标签体中,如果是文本框,数据会在文本框外显示,要想显示在文本框内,使用 th:value
<input type="text" id="realName" name="reaName" th:text="${realName}">
th:object
用于数据对象绑定
通常用于选择变量表达式(星号表达式)
th:onclick
<!--目前 thymeleaf 版本要求只能传递数字和布尔值-->
<a th:onclick="'show('+${user.id}+')'">点击:显示学生编号</a>
<script type="text/javascript">
function show(id) {
alert("用户编号为:" + id);
}
</script>
th:style
<a th:onclick="'show('+${user.id}+')'" th:style="'font-
size:40px;color:red;'">点击:显示学生编号</a>
th:each(常用)
类比jstl的c:foreach
来理解,var,item,status对应着user,${userList},userStat
- 遍历List集合
<div style="color: red">
1.user:当前对象的变量名<br/>
2.userStat:当前对象的状态变量名<br/>
3.${userList}:循环遍历的集合<br/>
4.变量名自定义
</div>
<div th:each="user,userStat:${userList}">
<span th:text="${userStat.index}"></span>
<span th:text="${user.id}"></span>
<span th:text="${user.name}"></span>
<span th:text="${user.phone}"></span>
</div>
代码说明
th:each=“user, iterStat : ${userlist}” 中的 ${userList} 是后台传过来的集合
- user
定义变量,去接收遍历${userList}集合中的一个数据 - iterStat
${userList} 循环体的信息 - 其中 user 及 iterStat 自己可以随便取名
- interStat 是循环体的信息,通过该变量可以获取如下信息
index: 当前迭代对象的 index (从 0 开始计算)
count: 当前迭代对象的个数(从 1 开始计算) 这两个用的较多
size: 被迭代对象的大小
current: 当前迭代变量
even/odd: 布尔值,当前循环是否是偶数/奇数(从 0 开始计算)
first: 布尔值,当前循环是否是第一个
last: 布尔值,当前循环是否是最后一个
注意:循环体信息 interStat 也可以不定义,则默认采用迭代变量加上 Stat 后缀,即 userStat
- 遍历Map集合
<div th:each="userMap,userMapStat:${userMaps}">
<span th:text="${userMapStat.count}"></span>
<span th:text="${userMap.key}"></span>
<span th:text="${userMap.value}"></span>
<span th:text="${userMap.value.id}"></span>
<span th:text="${userMap.value.name}"></span>
<span th:text="${userMap.value.phone}"></span>
</div>
- 遍历Array数组
<div th:each="user,userStat:${userArray}">
<span th:text="${userStat.count}"></span>
<span th:text="${user.id}"></span>
<span th:text="${user.name}"></span>
<span th:text="${user.phone}"></span>
</div>
- List中元素是存放List集合的Map对象
<div th:each="myListMap:${myList}">
<div th:each="myListMapObj:${myListMap}">
Map 集合的 key:<span th:text="${myListMapObj.key}"></span>
<div th:each="myListMapObjList:${myListMapObj.value}">
<span th:text="${myListMapObjList.id}"></span>
<span th:text="${myListMapObjList.name}"></span>
<span th:text="${myListMapObjList.phone}"></span>
</div>
</div>
</div>
th:if
th:unless
<h1>th:if 用法:如果满足条件显示,否则相反</h1>
<div th:if="${sex eq 1}">
男:<input type="radio" name="sex" th:value="1"/>
</div>
<div th:if="${sex eq 0}">
女:<input type="radio" name="sex" th:value="0"/>
</div>
<h1>th:unless 用法:与 th:if 用法相反,即对条件判断条件取反</h1>
<div th:unless="${sex == 1}">
男:<input type="radio" name="sex" th:value="1"/>
</div>
<div th:unless="${sex eq 0}">
女:<input type="radio" name="sex" th:value="0"/>
</div>
th:switch/th:case
<div th:switch="${sex}">
<span th:case="1">性别:男</span><br/>
<span th:case="2">性别:女</span><br/>
<span th:case="*">性别:保密</span>
</div>
一旦某个 case 判断值为 true ,剩余的 case 默认不执行 ,“* ”表示默认的 case ,前面的 case 都不匹配时候,执行默认的 case
th:inline
th:inline 有三个取值类型 (text, javascript 和 none),值为 none 什么都不做,没有效果
- th:inline=“text” 注意:一般我们将 th:inline=“text” 放到
<body th:inline="text">
。获取的是request域中的对象
<h1>标准变量表达式(展示数据)</h1>
用户编号:<span th:text="${user.id}"></span><br/>
用户姓名:<span th:text="${user.name}"></span><br/>
<h1>内敛文本 th:inline="text"</h1>
<div th:inline="text">
用户编号:<div>[[${user.id}]]</div><br/>
用户姓名:[[${user.name}]]<br/>
用户手机号:[[${user.phone}]]<br/>
用户地址:[[${user.address}]]<br/>
</div>
- th:inline=“javascript” 在 js 代码中获取后台的动态数据
<script type="text/javascript" th:inline="javascript">
function showInlineJavaScript() {
alert("欢迎 " + [[${user.name}]] + " 到我院指导工作!联系方式: " +
[[${user.phone}]]);
}
</script>
<button th:onclick="showInlineJavaScript()">展示内容</button>
Thymeleaf 字面量
字面量:对应数据类型的合法取值,可以在 html 页面直接使用,不需要后台传递
文本字面量
用单引号’…'包围的字符串为文本字面量,这里的文本字面量就是/user/info?id=
<h1>文本字面量:用单引号'...'包围的字符串</h1>
<a th:href="@{'/user/info?id=' + ${user.id}}">查看用户:文本字面的路径使用</a><br/>
<span th:text="您好"></span>
数字字面量
今年是<span th:text="2019">1949</span>年<br/>
20 年后,将是<span th:text="2019 + 20">1969</span>年<br/>
boolean 字面量
<div th:if="${success}">执行成功</div>
<div th:unless="${flag}">执行不成功</div>
null字面量
<span th:if="${user ne null}">用户不为空</span><br/>
<span th:unless="${user eq null}">用户不为空(使用 th:unless 取反)</span><br/>
Thymeleaf 字符串拼接
<span th:text="'共'+${totalRows}+'条'+${totalPage}+'页,当前第'+${currentPage}+'页'"></span>
<h1>另一种更优雅的方式:使用"|要拼接的内容|"减少字符串拼接的加号</h1>
<span th:text="|共${totalRows}条${totalPage}页,当前第${currentPage}页|"></span>
Thymeleaf 运算符
三元运算 :表达式?” 正确结果”:” 错误结果”
算术运算: :+ , - , * , / , %
关系比较: :> , < , >= , <= ( gt , lt , ge , le )
相等判断: :== , != ( eq , ne )
<body>
<h1>三元运算符</h1>
<span th:text="${sex eq 1 ? '男':'女'}"></span><br/>
<span th:text="${sex == 1 ? '男':'女'}"></span><br/>
20*8=<span th:text="20 * 8"></span><br/>
20/8=<span th:text="20 / 8"></span><br/>
20+8=<span th:text="20 + 8"></span><br/>
20-8=<span th:text="20 - 8"></span><br/>
<div th:if="5 > 2">5>2 是真的</div>
<div th:if="5 gt 2">5 gt 2 是真的</div>
</body>
Thymeleaf表达式基本对象
模板引擎提供了一组内置的对象,这些内置的对象可以直接在模板中使用,这些对象由 # 号开始引用,我们比较常用的内置对象
#request
#request 相 当 于 httpServletRequest 对 象,这是 3.x 版 本 , 若 是 2.x 版本使用 #httpServletRequest ,在页面获取应用的上下文根,一般在 js 中请求路径中加上可以避免 404
<body>
<script type="text/javascript" th:inline="javascript">
var basePath = [[${#httpServletRequest.getScheme() + "://" +
#httpServletRequest.getServerName() + ":" +
#httpServletRequest.getServerPort() +
#httpServletRequest.getContextPath()}]];
//获取协议名称
var scheme = [[${#request.getScheme()}]];
//获取服务 IP 地址
var serverName = [[${#request.getServerName()}]];
//获取服务端口号
var serverPort = [[${#request.getServerPort()}]];
//获取上下文根
var contextPath = [[${#request.getContextPath()}]];
var allPath = scheme+"://"+serverName+":"+serverPort+contextPath;
alert(allPath);
</script>
</body>
#session
相当于 HttpSession 对象,这是 3.x 版本,若是 2.x 版本使用 #httpSession
在后台方法中向 session 中放数据
@RequestMapping(value = "/index")
public String index(HttpServletRequest request) {
request.getSession().setAttribute("username","zhangsan");
return "index";
}
从页面获取数据(如果在使用#session和#httpSession的地方提示报错,可以改成session.对象名
来尝试获取)
<h1>从 SESSION 中获取用户名称</h1>
<span th:text="${#session.getAttribute('username')}"></span><br/>
<span th:text="${#httpSession.getAttribute('username')}"></span>
Thymeleaf 表达式功能对象(了解)
模板引擎提供的一组功能性内置对象,可以在模板中直接使用这些对象提供的功能方法工作中常使用的数据类型,如集合,时间,数值,可以使用 Thymeleaf 的提供的功能性对象来处理它们
内置功能对象前都需要加#号,内置对象一般都以 s 结尾
官方手册: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 等;
#objects: 对 objects 操作的实用方法;
#bools: 对布尔值求值的实用方法;
#arrays: 数组的实用方法;
#lists: list 的实用方法,比如<span th:text="${#lists.size(datas)}"></span>
#sets: set 的实用方法;
#maps: map 的实用方法;
#aggregates: 对数组或集合创建聚合的实用方法;