摘要
看完本文你将掌握如下知识点:
项目准备
依赖
1 2 3 4 5 6
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
|
开启spring boot对thymeleaf的支持
1 2 3 4 5 6 7 8 9
| spring.thymeleaf.enabled=true spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.mode=HTML
spring.thymeleaf.cache=false spring.thymeleaf.servlet.content-type=text/html
|
也可以通过@Bean的方式开启支持
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 26 27 28 29 30
| @Bean public ThymeleafViewResolver thymeleafViewResolver(){ log.info("thymeleafViewResolver"); ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); viewResolver.setTemplateEngine(templateEngine()); viewResolver.setOrder(1); viewResolver.setCharacterEncoding("UTF-8"); viewResolver.setContentType("text/html"); viewResolver.setCache(false); return viewResolver; }
@Bean public SpringResourceTemplateResolver templateResolver(){ SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); templateResolver.setApplicationContext(this.applicationContext); templateResolver.setPrefix("classpath:/templates/"); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode(TemplateMode.HTML); templateResolver.setCacheable(false); return templateResolver; }
@Bean public SpringTemplateEngine templateEngine(){ SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver()); templateEngine.setEnableSpringELCompiler(true); return templateEngine; }
|
开启html页面对thymeleaf语法的支持
1 2 3
| <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> </html>
|
语法
各种表达式语法
-
${…} 变量表达式,用于展示后台传递过来的变量(request和session中的值)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <input type="text" name="modify" th:value="${modify}"/> <input type="text" name="id" th:value="${dataObj.id}"/> <textarea name="logParamData" id="logParamData" th:text="${dataObj.logParamData}"></textarea>
以下两种方式效果一致 <span th:text="${dataObj.name}"></span> <span>[[${dataObj.name}]]</span>
字符串拼接,可以使用加号,也可以使用竖线,以下两种方式效果一致 <input type="checkbox" name="accessTypes" th:value="${item.id}+'_'+${type.id}" checked="checked"> [[${type.name}] <input type="checkbox" name="accessTypes" th:value="${|${item.id}_${type.id}|}" checked="checked"> [[${type.name}]
#dates与java.util.Date对象的方法对应,格式化、日期组件抽取等等 <td th:text="${#dates.format(item.logTime, 'yyyy-MM-dd')}"></td> <td>[[${#dates.format(item.logTime, 'yyyy-MM-dd')}]]</td>
|
-
#{…} 国际化消息表达式,用于展示message.properties等国际化资源文件中的内容
1 2 3 4 5 6 7 8
| <input type="checkbox" name="selectAll" id="selectAll" th:text="#{common.choose}"/>
消息中需要传递变量的情况,多个变量逗号分割 <strong th:text="#{common.page.summary(${_pageBean.pageCount},${_pageBean.total})}">
以下两种方式效果一致 <td th:text="#{common.operate}"></td> <td>[[#{common.operate}]]</td>
|
-
@{…} 链接url表达式,用于封装url,如contextPath补全
1 2 3 4 5
| <link th:href="@{/resource/css/netqin.css}" rel="stylesheet"/> 用两个竖线来拼接带表达式的字符串 <script type="text/javascript" th:src="@{|/resource/js/i18n/list.#{locale}.js|}"></script> 带请求参数的url,多个用逗号分割 <a th:href="@{/auth/systemLogger/edit.do(id=${item.id},flag=${flag})}" th:text="#{common.edit}"></a>
|
-
js和css中用到表达式时使用双中括号的方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var systemAddress = "[[${#httpServletRequest.getScheme() + '://' + #httpServletRequest.getServerName() + ':' + #request.getServerPort()}]]"
var ctxPath = "[[@{/}]]";
var serverPath = systemAddress + ctxPath;
var modify = "[[${modify}]]"; if(modify != "add"){ $("#password").attr("placeholder","[[#{user.detail.changeNotice}]]"); }
|
-
*{…} 选择变量表达式,用于简写变量名称,需要配合th:object一起使用
1 2 3 4 5 6 7 8 9
| <div th:object="${user}"> <p>firstName: <span th:text="*{firstName}"></span></p> <p>lastName: <span th:text="*{lastName}"></span></p> </div> 相当于 <div> <p>firstName: <span th:text="${user.firstName}"></span></p> <p>lastName: <span th:text="${user.lastName}"></span></p> </div>
|
-
~{...}
代码块表达式,用于在html中复用相同的结构
语法:~{templatename::fragmentname}
示例:
common/model.html,th:fragment="header"
指定代码块名称
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head th:fragment="header"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <META http-equiv="Pragma" content="no-cache"> <META http-equiv="Cache-Control" content="no-cache"> <META http-equiv="Expire" content="0"> <link th:href="@{/resource/css/bootstrap.min.css}" rel="stylesheet" /> <link th:href="@{/resource/css/ace.min.css}" rel="stylesheet" /> <link rel="stylesheet" th:href="@{/resource/css/font-awesome.min.css}" /> <script th:src="@{/resource/js/jquery-1.11.0.min.js}"></script> </head> <body> </body> </html>
|
demo.html,th:replace="common/model::header"
,模板名称::代码块名称
1 2 3 4 5 6 7
| <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <header th:replace="common/model::header"></header> <body> </body> </html>
|
说明:代码块表达式需要配合th属性(th:insert,th:replace,th:include)一起使用。
1 2 3
| th:insert:将代码块片段整个插入到使用了th:insert的HTML标签中, th:replace:将代码块片段整个替换使用了th:replace的HTML标签中, th:include:将代码块片段包含的内容插入到使用了th:include的HTML标签中,
|
遍历
简单示例
1 2 3 4 5 6 7 8 9 10 11
| <tr th:each="item:${results}"> <td> <input type="checkbox" name="ids" th:value="${item.id}" class="noborder"/> </td> <td th:text="${item.id}"></td> <td> [[${#dates.format(item.logTime, 'yyyy-MM-dd')}]] </td> <td th:text="${item.logDesc}"></td> <td th:text="${item.logUser}"></td> </tr>
|
带遍历状态的示例
1 2 3 4 5 6 7 8 9 10 11
| <tr th:each="item,status:${results}" th:class="${status.odd}? 'odd':'even'"> <td> <input type="checkbox" name="ids" th:value="${item.id}" class="noborder"/> </td> <td th:text="${item.id}"></td> <td> [[${#dates.format(item.logTime, 'yyyy-MM-dd')}]] </td> <td th:text="${item.logDesc}"></td> <td th:text="${item.logUser}"></td> </tr>
|
1 2 3 4 5 6 7
| index:当前遍历索引,从0开始 count:当前遍历索引,从1开始 size:总元素数量 current:每一次遍历的iter变量 even/odd:当前遍历是even还是odd,布尔属性 first:当前遍历是第一个,布尔属性 last:当前遍历是最后一个,布尔属性
|
遍历时可以自定义变量
1 2 3 4 5
| th:with:用于定义变量,多个使用逗号分割 <span th:each="type,status:${accessTypes}" th:with="shwoName=${item.id}+'_'+${item.name}"> [[${shwoName}]] <span th:if="${not status.last}">,</span> </span>
|
条件判断
th:if
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 判断为true时才会显示div,authorities为Set类型,所以判断是否包含时可以使用#sets.contains()方法,测试时发现使用#arrays.contains()方法时也可以 <div th:if="${dataObj.reserved}"> <li th:each="item:${dataObj.authorities}"> <input type="checkbox" name="authorities" th:value="${item.id}" th:if="${dataObj.authorities ==null or not #sets.contains(dataObj.authorities,item)}"> <input type="checkbox" name="authorities" th:value="${item.id}" checked="checked" th:if="${dataObj.authorities !=null and #sets.contains(dataObj.authorities,item)}"> <span th:text="${item.showNameRole}"></span> </li> </div>
如果要判断为false时才会显示div,可以判断值是否等于false,或者使用th:unless <div th:if="${dataObj.reserved==false}"> <li th:each="item:${dataObj.authorities}"> <input type="checkbox" name="authorities" th:value="${item.id}"><span th:text="${item.showNameRole}"></span> </li> </div>
<div th:unless="${dataObj.reserved}"> <li th:each="item:${dataObj.authorities}"> <input type="checkbox" name="authorities" th:value="${item.id}"><span th:text="${item.showNameRole}"></span> </li> </div>
|
1 2 3 4 5 6
| 值不为null 值为boolean且为true 值为数字且非0 值为字符且非0 值是字符串且不是:“false”,“off”,“no” 值是object,但不为null
|
th:switch 和 th:case
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| bool匹配 <div th:switch="${dataObj.reserved}"> <p th:case="true">true</p> <p th:case="false">false</p> </div>
字符串匹配,要加单引号 <div th:switch="${item.showNameRole}"> <p th:case="'admin'">administrator</p> <p th:case="'manager'">manager</p> </div>
<div th:switch="${item.showNameRole}"> <p th:case="'admin'">administrator</p> <p th:case="'manager'">manager</p> <p th:case="*">unknow</p> </div>
|
运算符
1 2
| + : ${item.id}+'_'+${type.id} |xxxx| : |The name is ${name}|
|
1 2
| + , - , * , / , % (二元运算符) - :负号(一元运算符)
|
1 2
| and :且,or :或 (二元运算符) !,not :非(一元操作符)
|
1 2
| > , < , >= , <= (gt , lt , ge , le) == , != (eq, ne)
|
表达式工具对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #dates 与java.util.Date对象的方法对应,格式化、日期组件抽取等等,如:${#dates.format(item.lastupdate, 'yyyy-MM-dd HH:mm:ss')} #temporals 支持jdk8中新增的LocalDate,LocalDateTime的格式化,如:${#temporals.format(item.updateTime, 'yyyy-MM-dd HH:mm:ss')},新版本的spring-boot-starter-thymeleaf中已经默认加入了thymeleaf-extras-java8time依赖 #calendars 类似#dates,与java.util.Calendar对象对应 #numbers 格式化数字对象的工具方法 #strings 与java.lang.String对应的工具方法:contains、startsWith、prepending/appending等等 #objects 用于对象的工具方法 #bools 用于布尔运算的工具方法 #arrays 用于数组的工具方法 #lists 用于列表的工具方法 #sets 用于set的工具方法 #maps 用于map的工具方法 #aggregates 用于创建数组或集合的聚合的工具方法 #messages 用于在变量表达式内部获取外化消息的工具方法,与#{…}语法获取的方式相同 #ids 用于处理可能重复出现(例如,作为遍历的结果)的id属性的工具方法
|
获取环境变量和application.properties中的值
1 2
| <img th:src="${@environment.getProperty('image.path') + item.path}" width="60px" height="90px" style="cursor: pointer">
|
使用springsecurity权限标签的方法
添加依赖
1 2 3 4 5
| <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency>
|
开启命名空间支持
1 2 3 4 5 6 7
| <html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> </html>
使用方式与jsp标签类似: <a th:href="@{/auth/systemLogger/edit.do}" class="btn btn-success btn-xs no-hover" th:text="#{common.create}" sec:authorize="hasRole('LOGGER_ADD')"></a> <button class="btn btn-danger btn-xs" id="delete" th:text="#{common.delete}" sec:authorize="hasRole('LOGGER_DELETE')"></button>
|
调用spring管理的bean的方法,以及获取HttpSession对象和HttpServletRequest对象
语法:${@beanName.methodName(param,…)}
说明:beanName就是注册时的名称
示例:
1 2 3
| #httpSession就是javax.servlet.http.HttpSession对象,可以简写为session #httpServletRequest就是javax.servlet.http.HttpServletRequest对象,可以简写为request <span th:text="${@commonService.clearSessionMessage(#httpServletRequest)}" style="display: none"></span>
|
调用类的静态方法
1 2
| <div th:with="authoritysString=${T(com.example.function.auth.util.AuthUtil).getAuthoritysHtmlString(dataObj.authorities)}"> </div>
|
参考资料