使用Thymeleaf 三大理由:
源码下载:springboot-web-thymeleaf-enhance
— Hey Man,Don't forget to Star or Fork . —
官方指南: Thymleaf 3.0 官方教程
温馨提示:Thymeleaf 最为显著的特征是增强属性,任何属性都可以通过th:xx 来完成交互,例如th:value最终会覆盖value属性。
${}
使用方法:直接使用th:xx = "${}"
获取对象属性 。例如:
<form id="userForm"> <input id="id" name="id" th:value="${user.id}"/> <input id="username" name="username" th:value="${user.username}"/> <input id="password" name="password" th:value="${user.password}"/> </form> <div th:text="hello"></div> <div th:text="${user.username}"></div>
*{}
使用方法:首先通过th:object
获取对象,然后使用th:xx = "*{}"
获取对象属性。
这种简写风格极为清爽,推荐大家在实际项目中使用。 例如:
<form id="userForm" th:object="${user}"> <input id="id" name="id" th:value="*{id}"/> <input id="username" name="username" th:value="*{username}"/> <input id="password" name="password" th:value="*{password}"/> </form>
@{}
使用方法:通过链接表达式@{}
直接拿到应用路径,然后拼接静态资源路径。例如:
<script th:src="@{/webjars/jquery/jquery.js}"></script> <link th:href="@{/webjars/bootstrap/css/bootstrap.css}" rel="stylesheet" type="text/css">
~{}
片段表达式是Thymeleaf的特色之一,细粒度可以达到标签级别,这是JSP无法做到的。
片段表达式拥有三种语法:
~{ viewName } 表示引入完整页面
~{ viewName ::selector} 表示在指定页面寻找片段 其中selector可为片段名、jquery选择器等
~{ ::selector} 表示在当前页寻找
使用方法:首先通过th:fragment
定制片段 ,然后通过th:replace
填写片段路径和片段名。例如:
<!-- /views/common/head.html--> <head th:fragment="static"> <script th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script> </head> <!-- /views/your.html --> <div th:replace="~{common/head::static}"></div>
在实际使用中,我们往往使用更简洁的表达,去掉表达式外壳直接填写片段名。例如:
<!-- your.html --> <div th:replace="common/head::static"></div>
值得注意的是,使用替换路径th:replace
开头请勿添加斜杠,避免部署运行的时候出现路径报错。(因为默认拼接的路径为spring.thymeleaf.prefix = classpath:/templates/
)
即通常的国际化属性:#{msg}
用于获取国际化语言翻译值。例如:
<title th:text="#{user.title}"></title>
在基础语法中,默认支持字符串连接、数学运算、布尔逻辑和三目运算等。例如:
<input name="name" th:value="${'I am '+(user.name!=null?user.name:'NoBody')}"/>
官方文档: 附录A: Thymeleaf 3.0 基础对象
官方文档: 附录B: Thymeleaf 3.0 工具类
${#ctx}
上下文对象,可用于获取其它内置对象。${#vars}
: 上下文变量。${#locale}
:上下文区域设置。${#request}
: HttpServletRequest对象。${#response}
: HttpServletResponse对象。${#session}
: HttpSession对象。${#servletContext}
: ServletContext对象。#strings
:字符串工具类#lists
:List 工具类#arrays
:数组工具类#sets
:Set 工具类#maps
:常用Map方法。#objects
:一般对象类,通常用来判断非空#bools
:常用的布尔方法。#execInfo
:获取页面模板的处理信息。#messages
:在变量表达式中获取外部消息的方法,与使用#{...}语法获取的方法相同。#uris
:转义部分URL / URI的方法。#conversions
:用于执行已配置的转换服务的方法。#dates
:时间操作和时间格式化等。#calendars
:用于更复杂时间的格式化。#numbers
:格式化数字对象的方法。#aggregates
:在数组或集合上创建聚合的方法。#ids
:处理可能重复的id属性的方法。想要遍历List
集合很简单,配合th:each
即可快速完成迭代。例如遍历用户列表:
<div th:each="user:${userList}"> 账号:<input th:value="${user.username}"/> 密码:<input th:value="${user.password}"/> </div>
在集合的迭代过程还可以获取状态变量,只需在变量后面指定状态变量名即可,状态变量可用于获取集合的下标/序号、总数、是否为单数/偶数行、是否为第一个/最后一个。例如:
<div th:each="user,stat:${userList}" th:class="${stat.even}?'even':'odd'"> 下标:<input th:value="${stat.index}"/> 序号:<input th:value="${stat.count}"/> 账号:<input th:value="${user.username}"/> 密码:<input th:value="${user.password}"/> </div>
如果缺省状态变量名,则迭代器会默认帮我们生成以变量名开头的状态变量 xxStat
, 例如:
<div th:each="user:${userList}" th:class="${userStat.even}?'even':'odd'"> 下标:<input th:value="${userStat.index}"/> 序号:<input th:value="${userStat.count}"/> 账号:<input th:value="${user.username}"/> 密码:<input th:value="${user.password}"/> </div>
四、条件判断
条件判断通常用于动态页面的初始化,例如:
<div th:if="${userList}"> <div>的确存在..</div> </div>
如果想取反则使用unless 例如:
<div th:unless="${userList}"> <div>不存在..</div> </div>
使用默认的日期格式(toString方法) 并不是我们预期的格式:Mon Dec 03 23:16:50 CST 2018
<input type="text" th:value="${user.createTime}"/>
此时可以通过时间工具类#dates
来对日期进行格式化:2018-12-03 23:16:50
<input type="text" th:value="${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}"/>
[[${xx}]]
,可以读取服务端变量,也可以调用内置对象的方法。例如获取用户变量和应用路径:<script th:inline="javascript"> var user = [[${user}]];` var APP_PATH = [[${#request.getContextPath()}]]; var LANG_COUNTRY = [[${#locale.getLanguage()+'_'+#locale.getCountry()}]]; </script>
Thymeleaf
只负责解析一级视图,不能识别外部标签JS里面的表达式。需要了解更多关于国际化的精彩描述请前往 SpringBoot 快速实现国际化i18n 。
例如在国际化文件中编写了user.title这个键值,然后使用#{}
读取这个KEY即可获取翻译。
<title th:text="#{user.title}">用户登陆</title>
======== 有了上述基础后 下面正式开始Thymeleaf 的详细教程 ==============
首先通过Spring Initializr创建项目,
然后在POM文件引入web 、thymeleaf
等依赖
<dependencies> <dependency><!--Web相关依赖--> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><!--页面模板依赖--> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency><!--热部署依赖--> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> </dependencies>
然后在src/main/resources/application.yml
配置页面路径:
spring: thymeleaf: cache: false #关闭缓存 prefix: classpath:/views/ #调整页面路径
接着在src/main/java/com/hehe/web/UserController
获取用户信息:
@RestController public class UserController { private List<User> userList = new ArrayList<>(); { userList.add(new User("1", "socks", "123456", new Date())); userList.add(new User("2", "admin", "111111", new Date())); userList.add(new User("3", "jacks", "222222", null)); } @GetMapping("/") public ModelAndView index() { return new ModelAndView("user/user", "userList", userList); } } public class User { private String id; private String username; private String password; private Date createTime; //请读者自行补充 构造器和 get/set方法.. }
开始编写公共页面:src/main/resources/views/common/head.html
,其中static
为页面片段:
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <!--声明static为页面片段名称--> <head th:fragment="static"> <link th:href="@{/webjars/bootstrap/css/bootstrap.css}" rel="stylesheet" type="text/css"/> <script th:src="@{/webjars/jquery/jquery.js}"></script> </head> </html>
接着编写用户列表页:src/main/resources/views/user/user.html
配合th:each
显示用户列表信息。
使用说明:这里 th:replace="common/head::static"
表示将引用${spring.thymeleaf.prefix}/common/head.html
的static
页面片段,值得注意的是由于替换路径默认会拼接前缀路径,所以开头切勿在添加斜杠,否则在打包成JAR部署运行时将提示报Templates not found...
。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title th:text="用户信息">User</title> <!--默认拼接前缀路径,开头请勿再添加斜杠,防止部署运行报错!--> <script th:replace="common/head::static"></script> </head> <body> <div th:each="user,userStat:${userList}" th:class="${userStat.even}?'even':'odd'"> 序号:<input type="text" th:value="${userStat.count}"/> 账号:<input type="text" th:value="${user.username}"/> 密码:<input type="password" th:value="${user.password}"/> 时间:<input type="text" th:value="${user.createTime}"/> 时间:<input type="text" th:value="${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}"/> </div> <script th:inline="javascript"> //通过内联表达式获取用户信息 var userList = [[${userList}]]; console.log(userList) </script> </body> </html>
然后编写单个用户页面:
至此大功告成,然后快速启动项目,如图所示:
快速启动项目
然后访问用户列表: http://localhost:8080,如图所示
然后访问单个用户: http://localhost:8080/user/1,如图所示: