本篇介绍 SpringBoot集成模板引擎Thymeleaf以及Thymeleaf模板引擎的相关语法
1.Thymeleaf模板引擎介绍
提示:Spring Boot 推荐使用 Thymeleaf 来代替 JSP ,
Thymeleaf 是一款用于渲染 XML/XHTML/HTML 5 内容的模板引擎。类似 JSP、Velocity、FreeMaker 等,它也可以轻易的与 Spring MVC 等 Web 框架进行集成作为 Web 应用的模板引擎。与其他模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。
例如:
1 | Velocity: <p>$message</p> |
如果将上面三句话插入到一个静态页面,直接打开该静态页面,Velocity显示$message,FreeMarker显示${message},Thymeleaf显示 Hello World!。能够友好显示数据的只有Thymeleaf
Thymeleaf 的作用域在 html 标签内,类似标签的一个属性来使用,这就是它的特点
2.开发环境搭建
1.添加依赖
小技巧
net.sourceforge.nekohtml 这个依赖对于开发很有用,因为thymeleaf的语法严格要求html5语法,必须有结束标签,配置该依赖后可以忽略这些问题,该依赖要和spring.thymeleaf.mode=LEGACYHTML5这个配置一起使用
1 | <dependency> |
2.编写页面
注意:
templates目录不存在,需要手动创建
引入thymeleaf 的约束一定要在html标签中引入
spring-boot项目静态文件目录:/src/java/resources/static
spring-boot项目模板文件目录:/src/java/resources/templates
所以新建立的.html文件应该放在/src/java/resources/templates下。
文章这里在/src/java/resources/templates 目录下新建index.html,内容如下
1 |
|
3.修改application.properties
1 | #thymelea模板配置 |
4.创建控制器
注意:
这里必须使用@Controller注解,不要使用@RestController
方法返回值中的页面不能带有.html后缀
1 | () |
5.测试
访问http://localhost:8080/thymeleafDemo
3.引入外部JS和CSS
这里以引入bootsstrap为例
##1.导入bootstrap所需相关文件
首先在resource/static目录下引入以下文件
2.在模板页面引入资源文件
语法说明
@{/js/jquery.js}相对于项目上下文(Context,亦即项目部署时的路径名)的相对路径,例如,假设部署的项目Context为 app ,则thymeleaf的写法和实际效果如下图。点击该链接时,访问的地址是http://{serverName}:{port}/app/js/jquery.js
打开resource/templates/index.html
修改head标签,在其中引入相关文件
1 | <head> |
3.使用bootstrap相关样式
1 | <body> |
4.th:模板语法
在模板语法中所有的表达式都应该用
${表达式}
包裹起来
显示数据
1 | <p th:text="${message}"></p> |
循环
1 | <tr th:each="user,userStat:${users}"> |
th:each属性用于迭代循环,语法:th:each=”obj,iterStat:${objList}”
迭代对象可以是java.util.List,java.util.Map,数组等;
iterStat称作状态变量,属性有:
index:当前迭代对象的index(从0开始计算)
count: 当前迭代对象的index(从1开始计算)
size:被迭代对象的大小
current:当前迭代变量
even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
first:布尔值,当前循环是否是第一个
last:布尔值,当前循环是否是最后一个
判断
1 | <a th:if="${'1' == flag}" > |
综合小案例
需求:在页面显示所有的姓名,隔行换色,如果是奇数行最后一个单元格则显示奇数,否则显示偶数
使用到的标签 th:text, th:if, th:each,th:class
控制器代码
1 | "/thymeleafDemo") ( |
页面代码
1 |
|
页面效果
附:th标签库
关键字 | 功能介绍 | 案例 |
---|---|---|
th:id | 替换id | <input th:id="'xxx' + ${collect.id}"/> |
th:text | 文本替换 | <p th:text="${collect.description}">description</p> |
th:utext | 支持html的文本替换 | <p th:utext="${htmlcontent}">conten</p> |
th:object | 替换对象 | <div th:object="${session.user}"> |
th:value | 属性赋值 | <input th:value="${user.name}" /> |
th:with | 变量赋值运算 | <div th:with="isEven=${prodStat.count}%2==0"></div> |
th:style | 设置样式 | th:style="'display:' + @{(${sitrue} ? 'none' : 'inline-block')} + ''" |
th:onclick | 点击事件 | th:onclick="'getCollect()'" |
th:each | 属性赋值 | tr th:each="user,userStat:${users}"> |
th:if | 判断条件 | <a th:if="${userId == collect.userId}" > |
th:href | 链接地址 | <a th:href="@{/login}" th:unless=${session.user != null}>Login</a> /> |
th:switch | 多路选择 配合th:case 使用 | <div th:switch="${user.role}"> |
th:case | th:switch的一个分支 | <p th:case="'admin'">User is an administrator</p> |
th:fragment | 布局标签,定义一个代码片段,方便其它地方引用 | <div th:fragment="alert"> |
th:include | 布局标签,替换内容到引入的文件 | <head th:include="layout :: htmlhead" th:with="title='xx'"></head> /> |
th:replace | 布局标签,替换整个标签到引入的文件 | <div th:replace="fragments/header :: title"></div> |
th:selected | selected选择框 选中 | th:selected="(${xxx.id} == ${configObj.dd})" |
th:src | 图片类地址引入 | <img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" /> |
th:inline | 定义js脚本可以使用变量 | <script type="text/javascript" th:inline="javascript"> |
th:action | 表单提交的地址 | <form action="subscribe.html" th:action="@{/subscribe}"> |
th:remove | 删除某个属性 | <tr th:remove="all"> 1.all:删除包含标签和所有的孩子。 |
th:attr | 设置标签属性,多个属性可以用逗号分隔 | 比如 th:attr="src=@{/image/aa.jpg},title=#{logo}" ,此标签不太优雅,一般用的比较少。 |
th:unless | 和th:if判断相反 | <a th:href="@{/login}" th:unless=${session.user != null}>Login</a> |