Thymeleaf
发表于|更新于
|字数总计:5.5k|阅读时长:24分钟|阅读量:
Thymeleaf 简介
Thymeleaf 是一个流行的模板引擎,该模板引擎采用 Java 语言开发 模板引擎是一个技术名词,是跨领域跨平台的概念,在 Java 语言体系下有模板引擎, 在 C#、 PHP 语言体系下也有模板引擎,甚至在 JavaScript 中也会用到模板引擎技术, Java 生 态下的模板引擎有 Thymeleaf 、 Freemaker、 Velocity、 Beetl(国产) 等。 Thymeleaf 对网络环境不存在严格的要求,既能用于 Web 环境下,也能用于非 Web 环 境下。在非 Web 环境下,他能直接显示模板上的静态数据;在 Web 环境下,它能像 Jsp 一 样从后台接收数据并替换掉模板上的静态数据。它是基于 HTML 的,以 HTML 标签为载体, Thymeleaf 要寄托在 HTML 标签下实现。 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
在pom文件添加Thymeleaf的依赖
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
|
添加Thymeleaf的配置
1 2 3 4 5 6 7
|
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
|
创建控制器,返回html视图的名称
1 2 3 4 5 6 7 8
| @Controller public class ThymeleafController { @RequestMapping(value = "/index") public String index(Model model) { model.addAttribute("data","SpringBoot 成功集成 Thymeleaf 模版! "); return "index"; } }
|
展示数据
在 src/main/resources 的 templates 下建一个 index.html 页面用于
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>SpringBoot 集成 Thymeleaf</title> </head> <body >
<span th:text="${data}"></span> <p th:text="${data}"></p> <div th:text="${data}"></div> </body> </html> 注 意 :Springboot使用thymeleaf作为视图展示, 约定将模板文件放置在src/main/resource/templates 目录下, 静态资源放置在 src/main/resource/static 目录下
|
Thymeleaf的基本内容
标准变量表达式
注意: th:text=”” 是 Thymeleaf 的一个属性,用于文本的显示
1 2
| 语法 ${} 说明 标准变量表达式用于访问容器( tomcat)上下文环境中的变量,功能和 EL 中的 ${} 相 同。 Thymeleaf 中的变量表达式使用 {变量名} 的方式获取 Controller 中 model 其中的数据
|
选择变量表达式
1 2 3 4 5 6
| 语法: *{...} 说明 选择变量表达式,也叫星号变量表达式,使用 th:object 属性来绑定对象 选择表达式首先使用 th:object 来绑定后台传来的 User 对象,然后使用 * 来代表这个对象,后面 {} 中的值是此对象中的属性。 选择变量表达式 *{...} 是另一种类似于标准变量表达式 ${...} 表示变量的方法 选择变量表达式在执行时是在选择的对象上求解,而${...}是在上下文的变量 Model 上求解,这种写法比标准变量表达式繁琐,了解即可
|
1 2 3 4 5 6 7 8
| <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>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <h2>标准变量表达式和选择变量表达式混用</h2> <h3>=======标准变量表达式=======</h3> 用户编号: <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/>
<h3>=======选择变量表达式=======</h3> 用户编号: *{user.id} ==> <span th:text="*{user.id}"></span><br/> 用户姓名: *{ user.name} ==> <span th:text="*{user.name}"></span><br/> 用户手机号: *{user.phone} ==> <span th:text="*{user.phone}"></span><br/> 用户地址: *{user.address} ==> <span th:text="*{user.address}"></span><br/>
|
内嵌表达式
- 文本内联
[[…]]
之间的表达式在Thymeleaf被认为是内联表达式,在其中您可以使用任何类型的表达式,也会有效th:text
属性。1 2 3
| <p>Hello, [[${session.user.name}]]!</p>
<p>Hello, <span th:text="${session.user.name}">Sebastian</span>!</p>
|
- 脚本内联
Thymeleaf提供一系列的“脚本”的内联模式功能,这样你就可以将你的数据在脚本中创建一些脚本语言。1 2 3 4 5 6 7 8 9
| <script th:inline="javascript"> var user = [[${user.username}]]; alert(user); </script>
<script th:inline="javascript"> var msg = 'Hello, ' + [[${user.username}]]; alert(msg); </script>
|
th:inline
内联text: 在html标签外,获取表达式的值
语法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <p>显示姓名是:[[${key}]]</p>
<div style="margin-left: 400px"> <h3>内联 text, 使用内联表达式显示变量的值</h3> <div th:inline="text"> <p>我是[[${name}]],年龄是[[${age}]]</p> 我是<span th:text="${name}"></span>,年龄是<span th:text="${age}"></span> </div>
<div> <p>使用内联text</p> <p>我是[[${name}]],性别是[[${sex}]]</p> </div> </div>
|
内联javascript
1 2 3 4 5 6 7 8 9 10 11
| 例子: <script type="text/javascript" th:inline="javascript"> var myname = [[${name}]]; var myage = [[${age}]];
function fun(){ alert("单击事件,获取数据 "+ myname + ","+ [[${sex}]]) } </script>
|
URL表达式
语法:@{}
主要用于链接、地址的展示, 可用于 <script src="...">
、 <link href="...">
、 <a href="...">
、 <form action="...">
、<img src="">
等,可以 在 URL 路径中动态获取数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <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> </body>
|
th:action
th:action 定义后台控制器的路径,类似
1 2 3 4 5 6
| <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>
|
1 2 3 4 5 6
| 思考:为什么后两个中${user.id} 获取不到数据? 因为我们 Thymeleaf 是以 html 为载体的,所以 html 不会认识${}语法。 我们请求的流程是,发送请求给服务器,服务器接收请求后,处理请求,跳转到指定的静 态 html 页面,在服务器端, Thymeleaf 模板引擎会按照它的语法,对动态数据进行处理, 所以如果要是 th 开头,模板引擎能够识别,会在服务器端进行处理,获取数据;如果没有 以 th 开头,那么 Thymeleaf 模板引擎不会处理,直接返回给客户端了。
|
th:method
设置请求方法
1 2 3
| <form id="login" th:action="@{/login}" th:method="post">......</form> <h1>th:method 属性的使用</h1> <form th:action="@{/user/login}" th:method="post"></form>
|
th:src
th:src 用于外部资源引入
比如<script>
标签的 src 属性, <img>
标签的 src 属性,常与@{}
表达式结 合使用,在 SpringBoot 项目的静态资源都放到 resources 的 static 目录下。 放到 static 路径下的内容,写路径时不需要写上 static
1 2 3 4 5 6 7 8 9 10 11
| <h1>th:src 属性的使用</h1>
<script src="/static/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" th:src="@{/jquery-1.7.2.min.js}"></script> <script> $(function () { alert("引入 js 文件"); }); </script>
|
这种方式比传统方式的好处是,在 URL 表达式前加/,会自动加上上下文根,避免 404 找不 到资源的情况
th:id
th:id 类似 html 标签中的 id 属性
1
| <span th:id="${hello}">aaa</span>
|
th:name
th:name 设置名称
1
| <input th:type="text" th:id="userName" th:name="userName">
|
th:value
th:value 类似 html 标签中的 value 属性,能对某元素的 value 属性进行赋值
1
| <input type="hidden" id="userId" name="userId" th:value="${userId}">
|
th:attr
th:attr 该属性也是用于给 HTML 中某元素的某属性赋值,好处是可以给 html 中没有定义的属性动 态的赋值
1 2 3 4
| <h1>th:attr 属性的使用</h1> <span zhangsan="${user.name}"></span>
<span th:attr="zhangsan=${user.name}"></span>
|
th:text
th:text 用于文本的显示,该属性显示的文本在标签体中,如果是文本框,数据会在文本框外显示, 要想显示在文本框内,使用th:value
1
| <input type="text" id="realName" name="reaName" th:text="${realName}">
|
th:object
th:object 用于数据对象绑定 通常用于选择变量表达式(星号表达式)
th:onclick
1 2 3 4 5 6 7 8
| <h1>th:onclick 的使用</h1>
<a th:onclick="'show('+${user.id}+')'">点击:显示学生编号</a> <script type="text/javascript"> function show(id) { alert("用户编号为: " + id); } </script>
|
th:style
th:style 设置样式
1 2
| <a th:onclick="'show('+${user.id}+')'" th:style="'font-size:40px;color:red;'">点击:显示学生编号</a>
|
th:each
比如从后台传来一个对象集合那么就可以使用此属性遍历输出,它与 JSTL 中的<c: forEach>类似,此属性既可以循环遍历集合,也可以循环遍历数组及 Map
1 2 3
| th:each 这个属性非常常用,比如从后台传来一个对象集合那么就可以使用此属性遍历输出,它与 JSTL 中的<c: forEach>类似,此属性既可以循环遍历集合,也可以循环遍历数组及 Map
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <body> <h1>th:each 循环遍历 List 集合</h1> <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> <span th:text="${user.address}"></span> </div> </body>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <head> <meta charset="UTF-8"> <title>循环遍历 Map 集合</title> </head> <body> <h1>th:each 循环遍历 Map 集合</h1> <div th:each="userMap,userMapStat:${userMaps}"> <span th:text="${userMapStat.count}"></span> <span th:text="${userMap.key}"></span> <span th:text="${userMap.value.id}"></span> <span th:text="${userMap.value.name}"></span> <span th:text="${userMap.value.phone}"></span> <span th:text="${userMap.value.address}"></span> </div> <span th:text="${userMap.value.id}"></span> <span th:text="${userMap.value.name}"></span> <span th:text="${userMap.value.phone}"></span> <span th:text="${userMap.value.address}"></span> </div>
|
遍历 Array 数组, 在 ThymeleafController 中的 eachArray 方法中准备数组数据
1 2 3 4 5 6 7 8 9 10 11 12 13
| <head> <meta charset="UTF-8"> <title>循环遍历 Array 数组</title> </head> <body> <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> <span th:text="${user.address}"></span> </div> </body>
|
th:if 与 th:unless
条件判断
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
| <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> <div th:if="${user1 eq null}"> <h3 style="color: red">用户未登录</h3> </div> <div th:unless="${user2 == null}"> 用户姓名: <span th:text="${user2.name}"></span> </div> <h1>从 session 中获取值</h1> <div th:if="${user3 != null}"> <span th:text="${user3.name}"></span> </div> </body>
|
th:switch 与 th:case
1 2 3 4 5 6
| <h1>th:switch/th:case 用法</h1> <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
文本字面量
用单引号’…’包围的字符串为文本字面量
1 2 3
| <h1>文本字面量:用单引号'...'包围的字符串</h1> <a th:href="@{'/user/info?id=' + ${user.id}}">查看用户:文本字面的路径使用</a><br/> <span th:text="您好"></span>
|
数字字面量
1 2 3
| <h1>数字字面量</h1> 今年是<span th:text="2019">1949</span>年<br/> 20 年后,将是<span th:text="2019 + 20">1969</span>年<br/>
|
boolean 字面量
1 2 3
| <h1>boolean 字面量</h1> <div th:if="${success}">执行成功</div> <div th:unless="${flag}">执行不成功</div>
|
null 字面量
1 2 3
| <h1>null 字面量</h1> <span th:if="${user ne null}">用户不为空</span><br/> <span th:unless="${user eq null}">用户不为空(使用 th:unless 取反) </span><br/>
|
Thymeleaf 字符串拼接
1 2 3 4 5
| <h1>文本字面量使用"+"拼接字符串</h1> <span th:text="'共'+${totalRows}+'条'+${totalPage}+'页,当前第'+${currentPage}+' 页'"></span> <h1>另一种更优雅的方式:使用"|要拼接的内容|"减少字符串拼接的加号</h1> <span th:text="|共${totalRows}条${totalPage}页,当前第${currentPage}页|"></span>
|
Thymeleaf 运算符
1 2 3 4
| 三元运算:表达式?”正确结果”:”错误结果” 算术运算: + , - , * , / , % 关系比较:: > , < , >= , <= ( gt , lt , ge , le ) 相等判断: == , != ( eq , ne )
|
Thymaleaf 表达式基本对象
模板引擎提供了一组内置的对象,这些内置的对象可以直接在模板中使用,这些对象由 #号开始引用,我们比较常用的内置对象
1 2 3
| #request #request 相 当 于 httpServletRequest 对 象 , 这 是 3.x 版 本 , 若 是 2.x 版 本 使 用 #httpServletRequest,在页面获取应用的上下文根,一般在 js 中请求路径中加上可以避免 404
|
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
| <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Thymeleaf 表达式基本对象</title> </head> <body> <script type="text/javascript" th:inline="javascript">
var basePath = [[${#httpServletRequest.getScheme() + "://" + #httpServletRequest.getServerName() + ":" + #httpServletRequest.getServerPort() + #httpServletRequest.getContextPath()}]];
var scheme = [[${#request.getScheme()}]];
var serverName = [[${#request.getServerName()}]];
var serverPort = [[${#request.getServerPort()}]];
var contextPath = [[${#request.getContextPath()}]];
var allPath = scheme+"://"+serverName+":"+serverPort+contextPath; alert(allPath)
|
1 2 3
| #session 相当于 HttpSession 对象,这是 3.x 版本,若是 2.x 版本使用#httpSession 在后台方法中向 session 中放数据
|
1 2 3
| <h1>从 SESSION 中获取用户名称</h1> <span th:text="${#session.getAttribute('username')}"></span><br/> <span th:text="${#httpSession.getAttribute('username')}"></span>
|
Thymeleaf 表达式功能对象
模板引擎提供的一组功能性内置对象,可以在模板中直接使用这些对象提供的功能方法 工作中常使用的数据类型,如集合,时间,数值,可以使用 Thymeleaf 的提供的功能性对象 来处理它们
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 内置功能对象前都需要加#号,内置对象一般都以 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: 对数组或集合创建聚合的实用方法;
|