thymeleaf是现代化服务器端的Java模板引擎,不一样于JSP和FreeMarker,Thymeleaf的语法更加接近HTML,而且也有不错的扩展性。详细资料能够浏览官网。html
本文主要介绍Thymeleaf模板的使用说明。thymeleaf模板等同于freemarker和Velocity。spring
一、定义和引用模板
浏览器
平常开发中,咱们常常会将导航栏、页尾、菜单等部分提取成模板供其它页面使用。服务器
在Thymeleaf 中,咱们可使用th:fragment
属性来定义一个模板。app
咱们能够新建一个简单的页尾模板,如:/WEB-INF/templates/footer.html,内容以下:less
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="copyright"> © 2016 xxx </div>
</body>
</html>
上面定义了一个叫作copyright
的片断,接着咱们可使用th:include
或者th:replace
属性来使用它:dom
<body> ... <div th:include="footer :: copyright"></div>
</body>
其中th:include中的参数格式为templatename::[domselector],
其中templatename是模板名(如footer),domselector是可选的dom选择器。若是只写templatename,不写domselector,则会加载整个模板。this
固然,这里咱们也能够写表达式:spa
<div th:include="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div>
模板片断能够被包含在任意th:*
属性中,而且可使用目标页面中的上下文变量。code
二、不经过th:fragment引用模板
经过强大的dom选择器,咱们能够在不添加任何Thymeleaf属性的状况下定义模板:
... <div id="copy-section">
© xxxxxx </div> ...
经过dom选择器来加载模板,如id为copy-section
<body> ... <div th:include="footer :: #copy-section">
</div>
</body>
三、th:include 和 th:replace区别
th:include 是加载模板的内容,而th:replace则会替换当前标签为模板中的标签
例如以下模板:
<footer th:fragment="copy">
© 2016
</footer>
咱们经过th:include 和 th:replace来加载模板
<body>
<div th:include="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
</body>
返回的HTML以下:
<body>
<div> © 2016 </div>
<footer>© 2016 </footer>
</body>
th:fragment定义模板的时候能够定义参数:
<div th:fragment="frag (onevar,twovar)">
<p th:text="${onevar} + ' - ' + ${twovar}">...</p>
</div>
在 th:include 和 th:replace中咱们能够这样传参:
<div th:include="::frag (${value1},${value2})">...</div>
<div th:include="::frag (onevar=${value1},twovar=${value2})">...</div>
此外,定义模板的时候签名也能够不包括参数:<div th:fragment="frag">
,咱们任然能够经过<div th:include="::frag (onevar=${value1},twovar=${value2})">...</div>
这种方式调用模板。
这其实和<div th:include="::frag" th:with="onevar=${value1},twovar=${value2}">
起到同样的效果
五、th:assert 断言
咱们能够经过th:assert来方便的验证模板参数
<header th:fragment="contentheader(title)" th:assert="${!#strings.isEmpty(title)}">...</header>
假设咱们有一个产品列表模板:
<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
<th>COMMENTS</th>
</tr>
<tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
<td>
<span th:text="${#lists.size(prod.comments)}">2</span> comment/s <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a>
</td>
</tr>
</table>
这时一个很常规的模板,可是,当咱们直接在浏览器里面打开它(不(不使用Thymeleaf ),它实在不是一个很好的原型。由于它的表格中只有一行,而咱们的原型须要更饱满的表格。
若是咱们直接添加了多行,原型是没有问题了,但经过Thymeleaf输出的HTML又包含了这些事例行。
这时经过th:remove属性,能够帮咱们解决这个两难的处境。
<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
<th>COMMENTS</th>
</tr>
<tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
<td>
<span th:text="${#lists.size(prod.comments)}">2</span> comment/s <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a>
</td>
</tr>
<tr class="odd" th:remove="all">
<td>Blue Lettuce</td>
<td>9.55</td>
<td>no</td>
<td>
<span>0</span> comment/s </td>
</tr>
<tr th:remove="all">
<td>Mild Cinnamon</td>
<td>1.99</td>
<td>yes</td>
<td>
<span>3</span> comment/s <a href="comments.html">view</a>
</td>
</tr>
</table>
其中th:remove的参数有以下几种:
固然,咱们也能够经过表达式来传参,
<a href="/something" th:remove="${condition}? tag : none">Link text not to be removed</a>
Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Tue Jan 16 00:42:03 CST 2018 There was an unexpected error (type=Internal Server Error, status=500). An error happened during template parsing (template: "class path resource [templates/index]")
异常缘由是:模板路径解析错误
解决办法:添加以下配置
#设置前缀和后缀
spring.thymeleaf.mode=HTML spring.thymeleaf.suffix=.html spring.thymeleaf.prefix=classpath:/templates/