Thymeleaf概述
- Thymeleaf是⾯向Web和独⽴环境的现代服务器端Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚⾄纯⽂本。
- Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。
SpringBoot整合Thymeleaf使用
-
可以在创建项目的时候导入相关的依赖或者手动引入依赖包
<!-- SpringBoot项目引入方式 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- 非SpringBoot项目引入方式 --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>2.1.4</version> </dependency>
-
Thymeleaf默认映射的模板路径就是resources下的templates目录
-
在主配置文件中配置Thymeleaf视图解析器
#thymeleaf start spring.thymeleaf.mode=HTML5 #实际项目中可能会有不太严格的HTML格式,此时设置mode=HTML5将会对非严格的报错,可以参考以下配置:#spring.thymeleaf.mode=LEGACYHTML5 用这种检查格式需要导入以下依赖: #<dependency> # <groupId>net.sourceforge.nekohtml</groupId> # <artifactId>nekohtml</artifactId> # <version>1.9.22</version> #</dependency> #最后重启项目就可以感受到不那么严格的thymeleaf了 spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.content-type=text/html #开发时关闭缓存,不然没法看到实时页面 spring.thymeleaf.cache=false #thymeleaf end
-
编写Controller
@Controller public class HelloController { private static final Logger log = LoggerFactory.getLogger(HelloController.class); @GetMapping(value = "/hello") public String hello(Model model) { String name = "jiangbei"; model.addAttribute("name", name); return "hello"; } }
-
编写HTML模板
<!DOCTYPE HTML> <!-- 注意导入Thymeleaf约束 --> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>hello</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> </head> <body> <!--/*@thymesVar id="name" type="java.lang.String"*/--> <p th:text="'Hello!, ' + ${name} + '!'">3333</p> </body> </html>
Thymeleaf基础语法
-
创建HTML文件时需要导入约束
<html xmlns:th="http://www.thymeleaf.org">
-
th常用的属性有:
th:text:文本替换 th:utext:支持html的文本替换 th:value:属性赋值 th:href:引入css文件或指定链接 th:src:引入图片或js文件 th:each:遍历循环元素 th:if:判断条件,类似的还有th:unless,th:switch,th:case th:insert:代码块引入,类似的还有th:replace,th:include,常用于公共代码块提取的场景 th:fragment:定义代码块,方便被th:insert引用 th:object:声明变量,一般和*{}一起配合使用,达到偷懒的效果 th:attr:设置标签属性,多个属性可以用逗号分隔
-
引入css,js文件
<!-- 注意路径 --> <link rel="stylesheet" th:href="@{mall/css/common.css}"> <script th:src="@{/admin/plugins/jquery/jquery.min.js}"></script>
-
获取变量值${…}
<p th:text="'Hello!, ' + ${name} + '!'">3333</p>
-
链接表达式@{…}
<a th:href="@{/admin/goods/edit}" th:class="${path}=='goods-edit'?'nav-link active':'nav-link'"></a> <!-- 链接不需要传递参数时:@{/xxx} --> <!-- 链接需要传递参数时:@{/xxx(k1=v1,k2=v2)} 对应url结构:xxx?k1=v1&k2=v2 --> <!-- 引入本地资源:@{/项目本地的资源路径} --> <!-- 引入外部资源:@{/webjars/资源在jar包中的路径} -->
-
消息表达式#{…},一般用于国际化的场景。
-
运算
-
字符串拼接
<!-- 方式一 --> <span th:text="'当前是第'+${page}+'页 ,共'+${page}+'页'"></span> <!-- 方式二 使用“|”减少了字符串的拼接 --> <span th:text="|当前是第${page}页,共${page}页|"></span>
-
三元运算符
<span th:text="${sex eq 0} ? '男' : '女'">未知</span> <span th:text="${user.sex} ? '男':'女'"></span>
-
默认值
<!-- 当前面的表达式值为null时,就会使用后面的默认值。注意:?:之间没有空格。 --> <span th:text="${user.name} ?: '二狗'"></span>
-
比较运算
gt (>), lt (<), ge (>=), le (<=), not (!), Also eq (==), neq/ne (!=)
-
算术运算符
<span th:text="${user.age}"></span> //21 <span th:text="${user.age}%2 == 0"></span> //false
-
-
循环
-
使用
th:each
指令来完成<!-- 遍历表格 --> <tr th:each="user : ${users}"> <td th:text="${user.name}">Onions</td> <td th:text="${user.age}">2.41</td> </tr> <!-- 遍历下拉框,如果要选中用户已选择的,加上th:selected="${company.id == user.companyId}" --> <select name="companyid"> <option value>请选择</option> <option th:each="company : ${companyList}" th:value="${company.companyid}" th:text="${company.companyname}"></option> </select>
-
-
逻辑判断
<tr th:each="test:${test}"> <!--判断成绩--> <td th:if="${test.Score} gt 0 and ${test.Score} lt 60">差</td> <td th:if="${test.Score} ge 60 and ${test.Score} le 70">中</td> <td th:if="${test.Score} gt 70 and ${test.Score} le 80">良</td> <td th:if="${test.Score} gt 80 and ${test.Score} le 90">优</td> <td th:if="${test.Score} gt 90 and ${test.Score} le 100">超级优秀</td> </tr> <br/> <tr th:each="test:${test}"> <!--判断成绩 一般只有两种情况的时候可以使用这种方式--> <td th:if="${test.Score} gt 0 and ${test.Score} lt 60">差</td> <!--除了这些条件之外的--> <td th:unless="${test.Score} gt 0 and ${test.Score} lt 60">及格</td> </tr>
-
分支控制switch
<tr th:each="test:${test}"> <td th:switch="${test.male}"> <span th:case="1">男</span> <span th:case="2">女</span> <!--其他情况--> <span th:case="*">未知</span> </td> </tr> <div th:switch="${user.role}"> <p th:case="'admin'">User is an administrator</p> <p th:case="#{roles.manager}">User is a manager</p> <p th:case="*">User is some other thing</p> </div>
-
单选按钮
<div class="row cl"> <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>性 别:</label> <div class="formControls col-xs-8 col-sm-9 skin-minimal"> <div class="radio-box"> <input name="gender" type="radio" th:attr ="checked=${user.getGender()=='1'?true:false}" id="sex-1" value="0"> <label >男</label> </div> <div class="radio-box"> <input type="radio" th:attr ="checked=${user.getGender()=='0'?true:false}" id="sex-2" name="gender" value="1"> <label >女</label> </div> </div> </div>
-
多选按钮
//多选回显 <div class="row cl"> <input type ="checkbox" name="role" th:each ="role : ${roleList}" th:value="${role.roleName}" th:text ="${role.roleName}" th:attr ="checked=${userinfo.userRole.contains(role.roleName)?true:false}"> </div>
-
单选按钮默认选择一个
<input type ="radio" name="repaymentType" th:each ="repaymentType,repaymentState:${repaymentTypeList}" th:value="${repaymentType.dictName}" th:text ="${repaymentType.dictName}" th:attr ="checked=${repaymentState.index==0?true:false}">
-
下拉框
<div class="row cl"> <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>角 色:</label> <div class="formControls col-xs-8 col-sm-9"> <span class="select-box"> <select class="select" id="rol" size="1" name="city" onchange="changerole()"> <option style="height: 50px;" th:selected="${role.getRoleid() eq user.getRole_id()}" th:each="role:${rolelist}">[[${role.rolename}]]</option> </select> </span> </div> <input style="display: none" id="role" value="" name="role"> </div> <div class="row cl"> <label class="form-label col-xs-4 col-sm-3"><span class="c-red">*</span>权 限:</label> <div class="formControls col-xs-8 col-sm-9"> <span class="select-box"> <select class="select" id="pri" name="" onchange="changeprivilege()"> <option style="height: 50px;" th:selected="${privilege.pid eq user.getPrivilege()}" th:each="privilege:${pList}">[[${privilege.pname}]]</option> </select> </span> </div> <input style="display: none" id="privilege" value="" name="privilege"> </div>
-
th:fragment定义一个共用的代码块
<div class="site-footer" th:fragment="footer-fragment"> <!-- 共用代码块内容,常见的有:侧边栏,头部导航栏,网页底部信息 --> </div>
-
th:replace引入共用的代码块(推荐使用)
<div th:replace="mall/footer::footer-fragment"></div>
-
th:action的用法
<form id="login-form" th:action="@{/login}">...</form>
-
关于Thymeleaf中 th:insert th:replace th:include三者的区别
th:insert
:保留自己的主标签,保留th:fragment的主标签。th:replace
:不要自己的主标签,保留th:fragment的主标签。th:include
:保留自己的主标签,不要th:fragment的主标签。(官方3.0后不推荐)
<!-- 举例说明 --> <!-- 共用的片段内容 --> <footer th:fragment="copy"> <script type="text/javascript" th:src="@{/plugins/jquery/jquery-3.0.2.js}"></script> </footer> <!-- 三种引入的方式 --> <div th:insert="footer :: copy"></div> <div th:replace="footer :: copy"></div> <div th:include="footer :: copy"></div> <!-- 依次对应的结果 --> <!-- th:insert --> <div> <footer> <script type="text/javascript" th:src="@{/plugins/jquery/jquery-3.0.2.js}"></script> </footer> </div> <!-- th:replace --> <footer> <script type="text/javascript" th:src="@{/plugins/jquery/jquery-3.0.2.js}"></script> </footer> <!-- th:include --> <div> <script type="text/javascript" th:src="@{/plugins/jquery/jquery-3.0.2.js}"></script> </div>
-
常用的内置方法
-
strings:字符串格式化方法,常用的Java方法它都有。比如:equals,equalsIgnoreCase,length,trim,toUpperCase,toLowerCase,indexOf,substring,replace,startsWith,endsWith,contains,containsIgnoreCase等
-
numbers:数值格式化方法,常用的方法有:formatDecimal等
-
bools:布尔方法,常用的方法有:isTrue,isFalse等
-
arrays:数组方法,常用的方法有:toArray,length,isEmpty,contains,containsAll等
-
lists,sets:集合方法,常用的方法有:toList,size,isEmpty,contains,containsAll,sort等
-
maps:对象方法,常用的方法有:size,isEmpty,containsKey,containsValue等
-
dates:日期方法,常用的方法有:format,year,month,hour,createNow等
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>ITDragon Thymeleaf 内置方法</title> </head> <body> <h2>ITDragon Thymeleaf 内置方法</h2> <h3>#strings </h3> <div th:if="${not #strings.isEmpty(itdragonStr)}" > <p>Old Str : <span th:text="${itdragonStr}"/></p> <p>toUpperCase : <span th:text="${#strings.toUpperCase(itdragonStr)}"/></p> <p>toLowerCase : <span th:text="${#strings.toLowerCase(itdragonStr)}"/></p> <p>equals : <span th:text="${#strings.equals(itdragonStr, 'itdragonblog')}"/></p> <p>equalsIgnoreCase : <span th:text="${#strings.equalsIgnoreCase(itdragonStr, 'itdragonblog')}"/></p> <p>indexOf : <span th:text="${#strings.indexOf(itdragonStr, 'r')}"/></p> <p>substring : <span th:text="${#strings.substring(itdragonStr, 2, 8)}"/></p> <p>replace : <span th:text="${#strings.replace(itdragonStr, 'it', 'IT')}"/></p> <p>startsWith : <span th:text="${#strings.startsWith(itdragonStr, 'it')}"/></p> <p>contains : <span th:text="${#strings.contains(itdragonStr, 'IT')}"/></p> </div> <h3>#numbers </h3> <div> <p>formatDecimal 整数部分随意,小数点后保留两位,四舍五入: <span th:text="${#numbers.formatDecimal(itdragonNum, 0, 2)}"/></p> <p>formatDecimal 整数部分保留五位数,小数点后保留两位,四舍五入: <span th:text="${#numbers.formatDecimal(itdragonNum, 5, 2)}"/></p> </div> <h3>#bools </h3> <div th:if="${#bools.isTrue(itdragonBool)}"> <p th:text="${itdragonBool}"></p> </div> <h3>#arrays </h3> <div th:if="${not #arrays.isEmpty(itdragonArray)}"> <p>length : <span th:text="${#arrays.length(itdragonArray)}"/></p> <p>contains : <span th:text="${#arrays.contains(itdragonArray, 5)}"/></p> <p>containsAll : <span th:text="${#arrays.containsAll(itdragonArray, itdragonArray)}"/></p> </div> <h3>#lists </h3> <div th:if="${not #lists.isEmpty(itdragonList)}"> <p>size : <span th:text="${#lists.size(itdragonList)}"/></p> <p>contains : <span th:text="${#lists.contains(itdragonList, 0)}"/></p> <p>sort : <span th:text="${#lists.sort(itdragonList)}"/></p> </div> <h3>#maps </h3> <div th:if="${not #maps.isEmpty(itdragonMap)}"> <p>size : <span th:text="${#maps.size(itdragonMap)}"/></p> <p>containsKey : <span th:text="${#maps.containsKey(itdragonMap, 'thName')}"/></p> <p>containsValue : <span th:text="${#maps.containsValue(itdragonMap, '#maps')}"/></p> </div> <h3>#dates </h3> <div> <p>format : <span th:text="${#dates.format(itdragonDate)}"/></p> <p>custom format : <span th:text="${#dates.format(itdragonDate, 'yyyy-MM-dd HH:mm:ss')}"/></p> <p>day : <span th:text="${#dates.day(itdragonDate)}"/></p> <p>month : <span th:text="${#dates.month(itdragonDate)}"/></p> <p>monthName : <span th:text="${#dates.monthName(itdragonDate)}"/></p> <p>year : <span th:text="${#dates.year(itdragonDate)}"/></p> <p>dayOfWeekName : <span th:text="${#dates.dayOfWeekName(itdragonDate)}"/></p> <p>hour : <span th:text="${#dates.hour(itdragonDate)}"/></p> <p>minute : <span th:text="${#dates.minute(itdragonDate)}"/></p> <p>second : <span th:text="${#dates.second(itdragonDate)}"/></p> <p>createNow : <span th:text="${#dates.createNow()}"/></p> </div> </body> </html>
-
-
常用标签