版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
Thymeleaf:
一、介绍:
1、Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。
2、Thymeleaf 开箱即用的特性。它提供标准和 Spring 标准两种方言,可以直接套用模板实现 JSTL、 OGNL表达式效果,避免每天套模板、改 Jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。
3、Thymeleaf 提供 Spring 标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
二、官网:
三、中文参考手册:
https://download.csdn.net/download/xiaofeivip_top/11426597
四、Maven:
<!-- SpringBoot集成thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
五、Thymeleaf对象的使用
1-文本国际化获取
html:
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#wbgjh">1、文本国际化获取</a>
</h5>
</div>
<div id="wbgjh" class="panel-collapse collapse">
<div class="panel-body">
<p class="text-left">1、普通获取方式:[[#{user.password.not.match}]]</p>
<p class="text-left">2、传入获取方式:[[#{user.password.retry.limit.exceed(${2})}]]</p>
</div>
</div>
</div>
messages.properties:
user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=密码输入错误{0}次
效果:
2-获取变量的方式
html:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#blfs">2、获取变量方式</a>
</h4>
</div>
<div id="blfs" class="panel-collapse collapse">
<div class="panel-body">
<p class="text-left">1、获取对象中的userName属性:[[${user.userName}]]</p>
<p class="text-left">2、获取集合中的元素:[[${users[1].userName}]]</p>
<p class="text-left">3、获取Map中的元素:[[${userMap['user1'].userName}]]</p>
<p class="text-left">4、获取数组中的元素:[[${userArr[1].userName}]]</p>
</div>
</div>
</div>
controller:
@GetMapping("/object")
public String object(ModelMap mmap) {
// 设置用户集合变量
List<SysUser> userList = new ArrayList<SysUser>();
SysUser user1 = new SysUser();
user1.setUserId(1L);
user1.setUserName("张三");
userList.add(user1);
SysUser user2 = new SysUser();
user2.setUserId(2L);
user2.setUserName("李四");
userList.add(user2);
mmap.put("user", user1);
mmap.put("users", userList);
// 设置Map变量
Map<String, SysUser> userMap = new HashMap<String, SysUser>();
userMap.put("user1", user1);
userMap.put("user2", user2);
mmap.put("userMap", userMap);
// 设置数组变量
SysUser[] userArr = new SysUser[]{user1, user2};
mmap.put("userArr", userArr);
// 设置数字对象
Double[] arr = new Double[]{100D, 155.941};
List list = Arrays.asList(arr);
@SuppressWarnings("unchecked")
Set set = new HashSet(list);
mmap.put("arr", arr);
mmap.put("list", list);
mmap.put("set", set);
return prefix + "/object";
}
效果:
3-处理转义文本
html:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#clzywb">3、处理转义文本</a>
</h4>
</div>
<div id="clzywb" class="panel-collapse collapse">
<div class="panel-body" th:with="html='<h3>小飞转义测试</h3>'">
1、转义字符输出
<p class="text-left" th:text="${html}"></p>
2、无需字符转义
<p class="text-left" th:utext="${html}"></p>
</div>
</div>
</div>
效果:
4-链接表达式
html:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#ljbds">4、链接表达式</a>
</h4>
</div>
<div id="ljbds" class="panel-collapse collapse">
<div class="panel-body">
<a th:href="@{/user/test(userId=${user.userId})}">设置单个URL参数</a>
<br/>
<a th:href="@{/user/test(userId=${user.userId},name=${user.userName})}">设置多个URL参数</a>
<br/>
<a th:href="@{/user/{userId}/test(userId=${user.userId})}">设置REST风格参数</a>
</div>
</div>
</div>
效果:
5-数字对象
html:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#szdx">5、数字对象</a>
</h4>
</div>
<div id="szdx" class="panel-collapse collapse">
<div class="panel-body" th:with="num=1000">
1、整数格式化---01000
<p class="text-left">[[${#numbers.formatInteger(num,5)}]]</p>
<!--/* 数组里面的整数格式化 */-->
<p class="text-left" th:each="arrNum : ${#numbers.arrayFormatInteger(arr,5)}">
[[${arrNum}]]
</p>
2、标识千位分隔符
<p class="text-left">POINT使用“.”作为分隔符:[[${#numbers.formatInteger(num,5, 'POINT')}]]</p>
<p class="text-left">COMMA使用“,”作为分隔符:[[${#numbers.formatInteger(num,5, 'COMMA')}]]</p>
<p class="text-left">WHITESPACE使用“ ”作为分隔符:[[${#numbers.formatInteger(num,5, 'WHITESPACE')}]]</p>
3、货币格式化---¥10.99
<p class="text-left">[[${#numbers.formatCurrency(10.99)}]]</p>
4、百分比格式化---23.456%
<p class="text-left">[[${#numbers.formatPercent(0.23456, 2, 3)}]]</p>
</div>
</div>
</div>
效果:
6-字符串对象
html:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#zfcdx">6、字符串对象</a>
</h4>
</div>
<div id="zfcdx" class="panel-collapse collapse">
<div class="panel-body">
1、toString与length方法
<p class="text-left">toString方法:[[${#strings.toString(user)}]]</p>
<p class="text-left">length方法:[[${#strings.length(user)}]]</p>
2、非空判断与默认值处理
<p class="text-left">isEmpty方法:[[${#strings.isEmpty(user.userName)}]]</p>
<p class="text-left">defaultString方法:[[${#strings.defaultString(user.sex,'无性别')}]]</p>
3、包含判断
<p class="text-left">contains方法:[[${#strings.contains(user.userName,'张三')}]]</p>
<!--/* 忽略大小写 */-->
<p class="text-left">containsIgnoreCase方法:[[${#strings.containsIgnoreCase(user.userName,'张三')}]]</p>
<!--/* 前面是否包含 */-->
<p class="text-left">startsWith方法:[[${#strings.startsWith(user.userName,'张')}]]</p>
<!--/* 后面是否包含 */-->
<p class="text-left">endsWith方法:[[${#strings.endsWith(user.userName,'三')}]]</p>
4、截取与替换
<!--/* 判断abcd里面有没有z */-->
<p class="text-left">indexOf 方法:[[${#strings.indexOf('abcd','z')}]]</p>
<!--/* 截取下标1-3字符 */-->
<p class="text-left">substring 方法:[[${#strings.substring('abcd', 1, 3)}]]</p>
<!--/* 截取a之前的 */-->
<p class="text-left">substringAfter 方法:[[${#strings.substringAfter('abcd', 'a')}]]</p>
<!--/* 截取a之后的 */-->
<p class="text-left">substringBefore 方法:[[${#strings.substringBefore('abcd', 'a')}]]</p>
<!--/* 把a替换为6 */-->
<p class="text-left">replace 方法:[[${#strings.replace('abcd', 'a', '6')}]]</p>
5、追加与拼接
<!--/* 在3后面追加e */-->
<p class="text-left">prepend 方法:[[${#strings.prepend(3, 'e')}]]</p>
<!--/* 在abcd后面追加e */-->
<p class="text-left">append 方法:[[${#strings.append('abcd', 'e')}]]</p>
<!--/* 在abcd后面追加e,b */-->
<p class="text-left">concat 方法:[[${#strings.concat('abcd', 'e', 'b')}]]</p>
<p class="text-left">concatReplaceNulls 方法:[[${#strings.concatReplaceNulls('**', '123', null, 'abc')}]]</p>
6、分割与连接
<p class="text-left" th:each="array : ${#strings.arraySplit('a-b-c', '-')}">
arraySplit方法:[[${array}]]
</p>
<p class="text-left">listSplit 方法:[[${#strings.arrayJoin(new String[]{'a','b','c'}, '-')}]]</p>
7、大小写转换
<p class="text-left">toUpperCase 方法:[[${#strings.toUpperCase('spring boot')}]]</p>
<p class="text-left">toLowerCase 方法:[[${#strings.toLowerCase('Spring Boot')}]]</p>
8、其他处理
<!--/* 去除空格 */-->
<p class="text-left">trim 方法:[[${#strings.trim(' spring boot ')}]]</p>
<!--/* 省略---spring... */-->
<p class="text-left">abbreviate 方法:[[${#strings.abbreviate('spring boot', 9)}]]</p>
<!--/* 随机出现字符 */-->
<p class="text-left">randomAlphanumeric 方法:[[${#strings.randomAlphanumeric(5)}]]</p>
</div>
</div>
</div>
效果:
7-日期对象
html:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#rqdx">7、日期对象</a>
</h4>
</div>
<div id="rqdx" class="panel-collapse collapse">
<div class="panel-body">
1、格式化日期
<p class="text-left">[[${#dates.format(new java.util.Date().getTime())}]]</p>
<p class="text-left">[[${#dates.formatISO(new java.util.Date().getTime())}]]</p>
<p class="text-left">[[${#dates.format(new java.util.Date().getTime(), 'yyy-MM-dd HH:mm:ss')}]]</p>
2、获取日期字段
<p class="text-left">获取当前的年份:[[${#dates.year(new java.util.Date().getTime())}]]</p>
<p class="text-left">获取当前的月份:[[${#dates.month(new java.util.Date().getTime())}]]</p>
<p class="text-left">获取当前的天数:[[${#dates.day(new java.util.Date().getTime())}]]</p>
<p class="text-left">获取当前的小时:[[${#dates.hour(new java.util.Date().getTime())}]]</p>
<p class="text-left">获取当前的分钟:[[${#dates.minute(new java.util.Date().getTime())}]]</p>
<p class="text-left">获取当前的秒数:[[${#dates.second(new java.util.Date().getTime())}]]</p>
<p class="text-left">获取当前的毫秒:[[${#dates.millisecond(new java.util.Date().getTime())}]]</p>
<p class="text-left">获取当前的月份名称:[[${#dates.monthName(new java.util.Date().getTime())}]]</p>
<p class="text-left">获取当前是星期几:[[${#dates.dayOfWeek(new java.util.Date().getTime())}]]</p>
</div>
</div>
</div>
效果:
六、Thymeleaf常用语法
1-表达式语法之运算符
html:
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#wbgjh">1、表达式语法之运算符</a>
</h5>
</div>
<div id="wbgjh" class="panel-collapse collapse">
<div class="panel-body" th:with="result = true">
<p class="text-danger">表达式常量</p>
<ul>
<li>
<p><strong>字符串常量</strong> - <span th:text="'hello, world'"></span></p>
</li>
<li>
<p><strong>数字常量</strong> - <span th:text="2019 + 1"></span></p>
</li>
<li>
<p><strong>布尔常量</strong> - <span th:text="${result}"></span></p>
</li>
<li>
<p><strong>空值常量</strong> - <span th:text="${result == null}"></span></p>
</li>
</ul>
<p class="text-danger">字符串拼接</p>
<ul>
<li>
<p><strong>方式一</strong> - <span th:text="${#strings.append('abc', 'd')}"></span></p>
</li>
<li>
<p><strong>方式二</strong> - <span th:text="${#strings.concat('abc', 'd')}"></span></p>
</li>
<li>
<p><strong>方式三</strong> - <span th:text="${'abc' + 'd'}"></span></p>
</li>
<li>
<p><strong>方式四</strong> - <span th:text="'abc' + 'd'"></span></p>
</li>
<li>
<p><strong>方式五</strong> - <span th:text="abc + d"></span></p>
</li>
<li>
<p><strong>方式六</strong> - <span th:text="|abc| + |d|"></span></p>
</li>
</ul>
<p class="text-danger">算数运算符</p>
<ul>
<li>
<p><strong>1 > 1 =</strong> <span th:text="${1 gt 1}"></span></p>
</li>
<li>
<p><strong>1 < 1 =</strong> <span th:text="${1 lt 1}"></span></p>
</li>
<li>
<p><strong>1 >= 1 =</strong> <span th:text="${1 ge 1}"></span></p>
</li>
<li>
<p><strong>1 <= 1 =</strong> <span th:text="${1 le 1}"></span></p>
</li>
</ul>
<p class="text-danger">三目运算符</p>
<ul>
<li>
<p><span th:text="${1 != 1} ? '条件成立' : '条件不成立'"></span></p>
</li>
</ul>
</div>
</div>
</div>
效果:
2-属性设置
html:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#blfs">2、属性设置</a>
</h4>
</div>
<div id="blfs" class="panel-collapse collapse">
<div class="panel-body">
<p class="text-left">1、单个属性值设置:<input type="submit" value="提交" th:attr="value=#{user.login.success}"></p>
<p class="text-left">2、多个属性值设置:<input type="submit" value="提交" th:attr="value=#{user.login.success},class='btn btn-primary'"></p>
<p class="text-left">3、设置单个HTML节点属性:<input type="submit" value="提交" th:value="#{user.login.success}"></p>
<p class="text-left">4、设置多个HTML节点属性:<input type="submit" value="提交" th:value="#{user.login.success}" th:class="'btn btn-primary'"></p></p>
<p class="text-left">5、属性值后面拼接:<div id="imgDiv1" th:attrappend="id='-dataId'"></div></p>
<p class="text-left">6、属性值前面拼接:<div id="imgDiv2" th:attrappend="id='dataId-'"></div></p>
<p class="text-left">8、属性添加style样式:<input type="submit" value="提交" style="text-align: left" th:styleappend="'clord:red'"></p>
<p class="text-left">9、属性添加class样式:<input type="submit" value="提交" class="btn btn-primary btn-xs" th:classappend="'btn-rounded'"></p>
</div>
</div>
</div>
效果:
源码:
3-条件判断
html:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#clzywb">3、条件判断</a>
</h4>
</div>
<div id="clzywb" class="panel-collapse collapse">
<div class="panel-body" >
<ul>
<li>
<p><strong>方式一</strong> - <span th:if="1">数字类型,如果为0,不显示</span></p>
<p><strong>方式二</strong> - <span th:if="true">false/off/on,不显示</span></p>
<select th:with="sex=1" th:switch="${sex}">
<option th:case="0">男</option>
<option th:case="1">女</option>
</select>
</li>
</ul>
</div>
</div>
</div>
效果:
4-数据迭代
html:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#ljbds">4、数据迭代</a>
</h4>
</div>
<div id="ljbds" class="panel-collapse collapse">
<div class="panel-body">
<p class="text-danger">list数据迭代</p>
<table class="table">
<tr th:each="user : ${users}">
<td th:text="${user.userName}"></td>
</tr>
</table>
<p class="text-danger">map数据迭代</p>
<table class="table">
<tr th:each="map : ${userMap}">
<td th:text="${map.key}"></td>
<td th:text="${map.value.userName}"></td>
</tr>
</table>
<p class="text-danger">数据状态对象(自定义规则节点变量名)</p>
<table class="table">
<thead>
<tr>
<td>用户名</td>
<td>从0开始的索引</td>
<td>从1开始的索引</td>
<td>数据集合大小</td>
<td>是否第一次迭代</td>
<td>是否最后一次迭代</td>
<td>是否偶数次迭代</td>
<td>是否奇数次迭代</td>
</tr>
</thead>
<tbody>
<tr th:each="user,state : ${users}">
<td th:text="${user.userName}"></td>
<td th:text="${state.index}"></td>
<td th:text="${state.count}"></td>
<td th:text="${state.size}"></td>
<td th:text="${state.first}"></td>
<td th:text="${state.last}"></td>
<td th:text="${state.even}"></td>
<td th:text="${state.odd}"></td>
</tr>
</tbody>
</table>
<p class="text-danger">数据状态对象(默认义规则节点变量名+Stat)</p>
<table class="table">
<thead>
<tr>
<td>用户名</td>
<td>从0开始的索引</td>
<td>从1开始的索引</td>
<td>数据集合大小</td>
<td>是否第一次迭代</td>
<td>是否最后一次迭代</td>
<td>是否偶数次迭代</td>
<td>是否奇数次迭代</td>
</tr>
</thead>
<tbody>
<tr th:each="user : ${users}">
<td th:text="${user.userName}"></td>
<td th:text="${userStat.index}"></td>
<td th:text="${userStat.count}"></td>
<td th:text="${userStat.size}"></td>
<td th:text="${userStat.first}"></td>
<td th:text="${userStat.last}"></td>
<td th:text="${userStat.even}"></td>
<td th:text="${userStat.odd}"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Controller:
@GetMapping("/commonly")
public String commonly(ModelMap mmap){
// 设置用户集合变量
List<SysUser> userList = new ArrayList<SysUser>();
SysUser user1 = new SysUser();
user1.setUserId(1L);
user1.setUserName("张三");
userList.add(user1);
SysUser user2 = new SysUser();
user2.setUserId(2L);
user2.setUserName("李四");
userList.add(user2);
mmap.put("user", user1);
mmap.put("users", userList);
// 设置Map变量
Map<String, SysUser> userMap = new HashMap<String, SysUser>();
userMap.put("user1", user1);
userMap.put("user2", user2);
mmap.put("userMap", userMap);
return prefix + "/commonly";
}
效果:
5-星号表达式
html:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#szdx">5、星号表达式</a>
</h4>
</div>
<div id="szdx" class="panel-collapse collapse">
<div class="panel-body" th:with="num=1000">
<table class="table">
<thead>
<tr>
<td>用户Id</td>
<td>用户名称</td>
</tr>
</thead>
<tbody>
<tr th:each="user : ${users}" th:object="${user}">
<td th:text="*{userId}"></td>
<td th:text="*{userName}"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
效果:
3、Thymeleaf模板片段
1-定义引用模板片段
html:
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#wbgjh">1、定义引用模板片段</a>
</h5>
</div>
<div id="wbgjh" class="panel-collapse collapse">
<div class="panel-body">
<p class="text-danger">定义引用模板片段(模板名称::选择器)</p>
th:insert:保留自己的主标签,保留th:fragment的主标签。
<br/>
th:replace:不要自己的主标签,保留th:fragment的主标签。
<br/>
th:include:保留自己的主标签,不要th:fragment的主标签。
<br/>
<a href="https://blog.csdn.net/xiaofeivip_top/article/details/91645262">详细请点击这里查看!</a>
</div>
</div>
</div>
效果:
具体请看:
https://blog.csdn.net/xiaofeivip_top/article/details/91645262
2-模板注释
html:
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#szdx">2、模板注释</a>
</h4>
</div>
<div id="szdx" class="panel-collapse collapse">
<div class="panel-body" th:with="num=1000">
1、注释可见
<!-- 检查源码可见 -->
2、注释不可见
<!--/* 检查源码不可见 */-->
</div>
</div>
</div>
源码:
七、Thymeleaf调用后台
1-Service:
@Service("dict")
public class DictService {
@Autowired
private ISysDictDataService dictDataService;
/**
* 根据字典类型查询字典数据信息
*
* @param dictType 字典类型
* @return 参数键值
*/
public List<SysDictData> getType(String dictType) {
// 查询数据库信息
return dictDataService.selectDictDataByType(dictType);
}
}
2-select标签的使用
html:
<select name="noticeType" th:with="type=${@dict.getType()}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.name}" th:value="${dict.id}"></option>
</select>
3-input标签的使用
<input type="text" th:value="${@dict.getInputValue()}" required>
4-js的使用
<script>
var types = [[${@dict.getInputValue()}]];
alert(types);
</script>
5-效果
QQ群:470765097