SpringBoot默认模板引擎Thymeleaf
官网地址
https://www.thymeleaf.org/index.html
概念:
Thymeleaf是面向Web和独立环境的现代服务器端Java模板引擎,能够处理Html,xml,JavaScript,css甚至存文本。
Thymeleaf 在提供一个优雅的,高度可维护的创建模式模板的方式。为了实现这一目标,Thymeleaf建立在自然模板的概念上,将其逻辑注入到模板文件中,不会影响模板设计原型。
Thymeleaf从设计之初就遵守web标准-特别是HTml5标准,如果需要,Thymeleaf允许创建完全符合HTML5验证标准模板。
SpringBoot 体系中默认推荐Thymeleaf作为前端页面模板,并且SpringBoot2.0中默认使用Thymeleaf3.0,性能提升幅度很大。
Thymeleaf特点
1 .Thymeleaf不管是否连接服务器的环境下皆可运行
2 .开箱即用。支持标准的方言和Spring方言,可以直接套用模板实现JSTL,OGNL表达式效果。
- Thymeleaf提供Spring标准方言和一个与SpringMVC完美集成的可选模块,可以快速的实现表单绑定,属性编辑器,国际化等功能
SpringBoot集成Thymeleaf
1.在pom.xml导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2.application.properties配置Thymeleaf
# thymeleaf 缓存,生产环境要放开
spring.thymeleaf.cache=false
3.spring boot对Thymeleaf的自动配置支持
org.springframework.boot.autoconfigure.thymeleaf
4.新建HTML文件
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--有服务器数据的时候 替换msg,没有就显示标签内的默认文字 -->
<p th:text="${msg}">这是静态标签文字</p>
</body>
</html>
Thymeleaf语法
th属性
官方文档地址
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#setting-value-to-specific-attributes
文本属性
文本拼接: |内容|
文本信息: th:text , th:id , th:value
<!--有服务器数据的时候 替换msg,没有就显示标签内的默认文字 -->
<p th:text="|welcome to Thymeleaf,${text}|"></p>
<!-- 字符拼接 -->
<p th:text="'welcome to Thymeleaf,'+${text}"></p>
<input th:value="${value}" th:id="${id}">
<br>
<!--text 将内容原样输出-->
<p th:text="${text}" ></p>
<!-- utext 输出内容会转义 -->
<p th:utext="${utext}" ></p>
条件属性
if 判断 : th:if
unless判断 : th:unless
switch判断 :th:switch th:case
<!--如果是超链接 必须使用 @{url}表达式,里面就可以用${url}的语法-->
<a th:if="${flag eq 'yes'}" th:href="@{${baidu}}">baidu_1</a><br>
<a th:if="${flag eq 'yes'}" th:href="@{ {baidusite}(baidusite=${baidu}) }">baidu_2</a><br>
<!--unless 取反-->
<a th:unless="${flag eq 'no'}" th:href="@{${baidu}}">baidu_3</a><br>
<!--swith-->
<div th:switch="${age}">
<p th:case="18">18岁</p>
<p th:case="19">19岁</p>
<p th:case="20">20岁</p>
<p th:case="*">未知</p>
</div><br>
循环属性 th:each
th:each迭代list
th:each的内置属性
th:tach迭代map
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h4>常用的方式</h4>
<table>
<tr>
<th>名字</th>
<th>年龄</th>
<th>密码</th>
</tr>
<tr th:each="user:${list}">
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
<td th:text="${user.pass}"></td>
</tr>
</table><br>
<h4>list 详细信息</h4>
<table>
<tr>
<th>名字</th>
<th>年龄</th>
<th>密码</th>
</tr>
<tr th:each="user,iterStat:${list}">
<td th:text="|索引:${iterStat.index};
元素总数:${iterStat.count};
current:${iterStat.current};
奇偶数:${iterStat.even?'奇数':'偶数'};
是第一个吗:${iterStat.first};
是最后一个吗:${iterStat.last}|"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
<td th:text="${user.pass}"></td>
</tr>
</table><br>
<h4>遍历map</h4>
<table border="2px" width="60%">
<tr th:each="m:${map}">
<td th:text="${m.key}"></td>
<td th:text="${m.value}"></td>
</tr>
</table>
<h4>遍历map的value是一个user对象</h4>
<table border="2px" width="60%">
<tr th:each="m:${map1}">
<td th:text="${m.key}"></td>
<td th:text="${m.value.name}"></td>
<td th:text="${m.value.age}"></td>
<td th:text="${m.value.pass}"></td>
</tr>
</table>
<h4>遍历map的value是一个list user对象</h4>
<div th:each="m:${map2}">
<p th:text="${m.key}"></p>
<table border="2px" width="60%">
<tr th:each="m1:${m.value}" >
<td th:text="${m.key}"></td>
<td th:text="${m1.name}"></td>
<td th:text="${m1.age}"></td>
<td th:text="${m1.pass}"></td>
</tr>
</table>
</div>
</body>
</html>
表达式语法
1 .简单表达式:
变量表达式: ${...}
选择变量表达式: *{...}
消息表达: #{...}
链接URL表达式: @{...}
片段表达式: ~{...}
2 . 文字
文本文字:'one text','Another one!',...
号码文字:0,34,3.0,12.3,...
布尔文字:true,false
空文字: null
文字标记:one,sometext,main,...
3 .文字操作:
字符串串联: +
文字替换: |The name is ${name}|
4 .算术运算:
二元运算符:+,-,*,/,%
减号(一元运算符): -
5 .布尔运算:
二元运算符:and,or
布尔否定(一元运算符): !,not
6 .比较和平等:
比较:>,<,>=,<=(gt,lt,ge,le)
等号运算符:==,!=(eq,ne)
7 .条件运算符:
如果-则: (if) ? (then)
如果-则-否则: (if) ? (then) : (else)
默认: (value) ?: (defaultvalue)
8 .特殊令牌:
无操作: _
${...} :
变量表达式,也叫SpringEL表达式,OGNL
1 .用于调用各种属性和方法;
2 .获取对象的属性和方法
3 .可以使用ctx,vars,locale,request,response,session,servletContext内置对象
4 .可以使用dates,numbers,strings,objects,arrays,lists,sets,maps等内置方法
@{...} :
链接表达式,不管是静态资源的引用,form表单的请求,凡是链接都可以用@{..}
1 .无参 : @{/xxx}
2 .有参 : @{/xxx(k1=v1,k2=v2)} , 对应url结构:xxx?k1=v1&k2=v2
3 .引入本地资源 :@{/项目本地的资源路径}
4 .引入外部资源 : @{/webjars/资源在jar包中的路径}
<!--引入外部资源-->
<link th:href="@{/webjars/bootstrap/4.5.0/css/bootstrap.css}" rel="stylesheet">
<!--引入本地资源-->
<link th:href="@{/main/css/itdragon.css}" rel="stylesheet">
<!--表单提交路径-->
<form class="form-login" th:action="@{/user/login}" th:method="post"></form>
<!--超链接跳转路径附带参数-->
<a class="btn btn-sm" th:href="@{/login.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/login.html(l='en_US')}">English</a>
webjars 网站资源:https://www.webjars.org/
例如:集成bootstrap
<!--bootstrap 前端架包-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.5.0</version>
</dependency>
#{...} :消息表达式:
用于从消息源中提取消息内容实现国际化
1 .语法与变量表达式相比多了个获取参数的方式
2 .消息源主要是properties文件
~{...} 代码块 表达式:
把某一段定义好的代码插入到另一个页面中,一般用于定义出一套通用的header或者footer
语法:~{templatename::fragmentname} 或者 ~{templatename::#id} , 如果省略templatename,它将在当前页面进行寻找指定的代码块,注意,~{} 可以省略;
1 . templatename: 模板名,定义模板的写法:<footer th:fragment="copy">
2 . fragmentname: 片段名,引入模板的写法:<div th:insert="comm/foot::copy">
3 .id: HTML 的id选择器,使用时要在前面加上#号,不支持class选择器
代码表达式需要配合th属性(th:insert,th:replace,th:include)一起使用功能:
1 .th:insert : 将代码块整个插入到使用了 th:insert 的HTML标签中
2 .th:replace : 将代码块段整个替换使用了 th:replace 的HTML标签中
3 . th:include : 将代码块片段包含的内容插入到使用了 th:include 的HTML标签
*{...} 选择变量表达式:
是另一种类似{...} 是在上下文的变量Map上求解。
两者获取对象里面属性的方式
两者混用的条件
基础对象
官方文档 :4.2 基础对象
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#expression-basic-objects
在上下文变量上评估OGNL表达式时,某些对象可用于表达式,以提高灵活性。这些对象将以#
符号开头(按照OGNL标准)被引用:
-
#ctx
:上下文对象。 -
#vars:
上下文变量。 -
#locale
:上下文语言环境。 -
#request
:(仅在Web上下文中)HttpServletRequest
对象。 -
#response
:(仅在Web上下文中)HttpServletResponse
对象。 -
#session
:(仅在Web上下文中)HttpSession
对象。 -
#servletContext
:(仅在Web上下文中)ServletContext
对象。
param:获取请求参数
session:访问session属性
application:获取应用程序 Servlet上下文属性
param,session,application都有方法:size(),isEmpty(),containsKey(), .key
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>base object</title>
</head>
<body>
<h1>base object 上下文 ctx保存了所有的信息</h1>
<p th:text="${#ctx}"></p>
<h1> ctx 获取map 数据</h1>
<p th:text="${#ctx.getVariable('a')}"></p>
<h1> vars上下文对象 和 ctx 内容差不多</h1>
<p th:text="${#vars}"></p>
<h1> 获取 local区域对象 </h1>
<p th:text="${#locale}"></p>
<p th:text="${#locale.country}"></p>
<h1> param 使用 </h1>
<!--http://localhost:8080/baseobject?a=12&b=3-->
<p th:text="|size:${param.size()},a:${param.a}|"></p>
<h1> session 使用 </h1>
<p th:text="${#session.getAttribute('session')}"></p>
<p th:text="${session.session}"></p>
<br>
</body>
</html>
常用工具类
除了这些基本对象之外,Thymeleaf将为我们提供一组实用程序对象,这些对象将帮助我们在表达式中执行常见任务。
-
#execInfo
:有关正在处理的模板的信息。 -
#messages
:用于获取变量表达式内的外部化消息的方法,与使用#{…}语法获得消息的方法相同。 -
#uris
:用于转义部分URL / URI的方法 -
#conversions
:用于执行已配置的转换服务(如果有)的方法。 -
#dates
:java.util.Date
对象的方法:格式化,组件提取等。 -
#calendars
:类似于#dates
,但用于java.util.Calendar
对象。 -
#numbers
:格式化数字对象的方法。 -
#strings
:String
对象的方法:包含,startsWith,前置/附加等。 -
#objects
:一般对象的方法。 -
#bools
:布尔值评估的方法。 -
#arrays
:数组方法。 -
#lists
:列表方法。 -
#sets
:套方法。 -
#maps
:地图方法。 -
#aggregates
:用于在数组或集合上创建聚合的方法。 -
#ids
:用于处理可能重复的id属性的方法(例如,由于迭代的结果)。
表达工具对象 官方文档:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-b-expression-utility-objects
详细介绍用法:
内联标签 body 内的内联
官方文档:
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#inlining
内联表达式:
[[...]] 或 [(...)]
[[...]]对应于th:text(即结果将被HTML转义)
[(...)]对应于th:utext 且将不执行任何HTML转义
<!-- 内联 1 标签 原样输出-->
<p>hello ,[[|welcome ,${text}|]]</p>
<!-- 内联 2 标签 文本带有转义会解析-->
<p>[('welcome ,'+${text})]</p>
<!-- 内联 3 标签 存文本输出-->
<p>[('welcome ')]</p>
<!--是内联失效 th:inline="none" -->
Js内联
JavaScript中使用内联标签(默认不支持):
在script 标签上引入对内联的支持:
<script th:inline="javascript">
...
//获取后端的数据
var username = [[${session.user.name}]];
var username2 = [(${session.user.name2})];
...
</script>
官方文档:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#javascript-inlining
在JavaScript中实现前后端分离(即JavaScript自然模板):
Thymeleaf 的目标是希望前后端分离,即同一个html文件前端开发以静态原型打开,看到的是他们的内容,而后端开发打开通过服务器,看到是动态的数据;
直接在数据上使用js注释实现前后端分离:
<script th:inline="javascript">
...
// /*...*/ 注释里的值是动态获取的,后面的是默认值
var username = /*[[${session.user.name}]]*/ "Gertrud Kiwifruit";
...
</script>
在JavaScript中自动进行对象序列化:
内联表达式的计算结果不限于字符串,它能自动将后台的数据序列化为JavaScript对象。
js开启内联标签模式只能在html文件内部的JavaScript代码中,不能在引入外部的JavaScript文件中操作。
<script th:inline="javascript">
...
//session.user是一个user对象
var user = /*[[${session.user}]]*/ null;
// 获取到对象,自动序列化
var user = {"age":null,"firstName":"John","lastName":"Apricot",
"name":"John Apricot","nationality":"Antarctica"};
...
</script>
CSS内联
官方文档:
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#css-inlining
在CSS中使用内联标签(默认不支持):
在style标签引入对内联的支持:
在css中,因为css自然模板,所以不能在css中添加注释说明,Thymeleaf会将它们当成模板处理。
CSS内联标签模式只能在html文件内部的style标签中,不能在引入外部关联的css文件中操作。
<style th:inline="css">
...
</style>
在style标签里书写 [[]],[()]来获取后端数据
在CSS中实现前后端分离(即CSS自然模板):
CSS内联也允许<style>标签静态和动态工作,通过注释中包含内联表达式作为css自然模板。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 内联标签-->
<style type="text/css" th:inline="css"
th:with="color='yellow',fontSize='25px'">
p{
color: /*[[${color}]]*/ red;
/*[(...)] 不转义;在css中,这种注释说明不能出现,会报错*/
font-size: [(${fontSize})];
}
</style>
</head>
<body>
//使用 p 标签
<p>hello china</p>
</body>
</html>