Thymeleaf模板引擎的主要目标是将优雅的自然模板带到开发工作流程中,并将HTML在浏览器中正确显示,并且可以作为静态原型,让开发团队能更容易地协作。Thymeleaf能够处理HTML,XML,JavaScript,CSS甚至纯文本。
长期以来,jsp在视图领域有非常重要的地位,随着时间的变迁,出现了一位新的挑战者:Thymeleaf,Thymeleaf是原生的,不依赖于标签库.它能够在接受原始HTML的地方进行编辑和渲染.因为它没有与Servelet规范耦合,因此Thymeleaf模板能进入jsp所无法涉足的领域。
Thymeleaf在Spring Boot项目中放入到resources/templates中。这个文件夹中的内容是无法通过浏览器URL直接访问的(和WEB-INF效果一样),所有Thymeleaf页面必须先走控制器。
整合步骤
一 添加依赖
<!--配置Thymeleaf模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.5.4</version>
</dependency>
Thymeleaf默认配置前缀和后缀,所以我们在返回跳转页面时不用加前缀和后缀,只写文件名就行
@Controller
public class ThymeleafController {
@RequestMapping("showIndex")
public String showIndex(){
return "index";
}
}
二 Thymeleaf基础语法
Thymeleaf通过标准变量表达式完成数据的展示和处理
1 标准变量表达式必须依赖标签,不能独立使用
2 标准变量表达式一般在开始标签中,以 th开头
3 语法为: <tag th:***="${key}" ></tag>
4 表达式中可以通过${}取出域中的值并放入标签的指定位置
5 ${}在这里不能单独使用,必须在 th:后面的双引号里使用
为了有提示,修改html页面中<html>标签为:
<html xmlns:th="http://www.thymeleaf.org" >
提示例如:
<input th:type="" th:text="${}" th:style="" th:id="" th:class="" ... ... >
th:text属性 :向HTML标签内部输出信息
如:controller
@RequestMapping("showIndex")
public String showIndex(Map<String,Object> map){
map.put("msg", "testMessage");
return "index";
}
页面代码
<!--向span双标签内部添加文本-->
<span th:text="pageMessage"></span> <br/>
<!--从域中根据参数名取出参数值放在双标签中-->
<span th:text="${msg}"></span> <br/>
th:value :表单元素,设置HTML标签中表单元素value属性时使用
<!--向input标签中的value属性赋值-->
<input type="text" th:value="pageMessage"/>
<!--从域中根据参数名取出参数值 向input标签中的value属性赋值-->
<input type="text" th:value="${msg}"/>
th:if : 条件判断
<span th:if="${name}!='张三'">会显示</span>
th:each:循环遍历
示例中u为迭代遍历。
- th:each="u,i :${list}" 其中i表示迭代状态。
- 1,index:当前迭代器的索引 从0开始
- 2,count:当前迭代对象的计数 从1开始
- 3,size:被迭代对象的长度
- 4,even/odd:布尔值,当前循环是否是偶数/奇数 从0开始
- 5,first:布尔值,当前循环的是否是第一条,如果是返回true否则返回false
- 6,last:布尔值,当前循环的是否是最后一条,如果是则返回true否则返回false
controller:
public class ThymeleafController {
@Autowired
private EmpService empService;
@RequestMapping("/showEmp")
public String showEmp(Map<String, Object> map) {
List<Emp> empList = empService.findAll();
map.put("empList", empList);
map.put("emp", empList.get(0));
return "showEmp";
页面模板代码
1. <!DOCTYPE html>
2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
3. <head>
4. <meta charset="UTF-8">
5. <title>Title</title>
6. <style type="text/css">
7. #empTable{
8. width: 80%;
9. border: 1px solid blue;
10. margin: 0px auto;
11. }
12. #empTable th,td{
13. border: 1px solid green;
14. text-align: center;
15. }
16. </style>
17. </head>
18. <body>
19. 展示单个员工信息:
20. <span th:if="${emp}!=null">
21. 工号:<span th:text="${emp.empno}"></span><br/>
22. 姓名:<span th:text="${emp.ename}"></span><br/>
23. 职务:<span th:text="${emp.job}"></span><br/>
24. 上级:<span th:text="${emp.mgr}"></span><br/>
25. 入职日期:<span th:text="${emp.hiredate}"></span><br/>
26. 工资:<span th:text="${emp.sal}"></span><br/>
27. 补助:<span th:text="${emp.comm}"></span><br/>
28. 部门号:<span th:text="${emp.deptno}"></span><br/>
29. </span>
30. <hr/>
31. <span th:if="${empList}!=null">
32. <span th:if="${empList.size()} ne 0">
33. 工号:<span th:text="${empList[0].empno}"></span><br/>
34. 姓名:<span th:text="${empList[0].ename}"></span><br/>
35. 职务:<span th:text="${empList[0].job}"></span><br/>
36. 上级:<span th:text="${empList[0].mgr}"></span><br/>
37. 入职日期:<span th:text="${empList[0].hiredate}"></span><br/>
38. 工资:<span th:text="${empList[0].sal}"></span><br/>
39. 补助:<span th:text="${empList[0].comm}"></span><br/>
40. 部门号:<span th:text="${empList[0].deptno}"></span><br/>
41. </span>
42. </span>
43. <table id="empTable" cellpadding="0px" cellspacing="0px">
44. <tr>
45. <th>索引</th>
46. <th>序号</th>
47. <th>总人数</th>
48. <th>偶数索引?</th>
49. <th>奇数索引?</th>
50. <th>第一?</th>
51. <th>最后?</th>
52. <th>工号</th>
53. <th>姓名</th>
54. <th>职务</th>
55. <th>上级</th>
56. <th>入职日期</th>
57. <th>工资</th>
58. <th>补助</th>
59. <th>部门号</th>
60. </tr>
61. <tr th:each="emp,i:${empList}">
62. <td th:text="${i.index}"></td>
63. <td th:text="${i.count}"></td>
64. <td th:text="${i.size}"></td>
65. <td th:text="${i.odd}"></td>
66. <td th:text="${i.even}"></td>
67. <td th:text="${i.first}"></td>
68. <td th:text="${i.last}"></td>
69. <td th:text="${emp.empno}"></td>
70. <td th:text="${emp.ename}"></td>
71. <td th:text="${emp.job}"></td>
72. <td th:text="${emp.mgr}"></td>
73. <td th:text="${emp.hiredate}"></td>
74. <td th:text="${emp.sal}"></td>
75. <td th:text="${emp.comm}"></td>
76. <td th:text="${emp.deptno}"></td>
77. </tr>
78.
79. </table>
80.
81. </body>
82. </html>
页面效果
三 标准变量表达式运算符支持
标准变量表达式支持的运算符
1.算数运算符
算术运算:+ , - , * , / , %
1. <span th:text="1+1"></span>
2. <span th:text="'1'+1"></span>
3. <span th:text="${emp.empno}+1"></span>
4. <span th:text="${emp.empno+1}"></span>
2.关系运算符
gt: great than(大于)> ge: great equal(大于等于)>= eq: equal(等于)== lt: less than(小于)< le: less equal(小于等于)<= ne: not equal(不等于)!=
3.逻辑运算符
&& 或 and: 表示并且
|| 或 or : 表示或者
1. <div th:text="1>0 and 2<3"></div>
2. <div th:text="1>0 and 2>3"></div>
3. <div th:text="1>0 or 2<3"></div>
4. <div th:text="1>0 or 2>3"></div>
5. <hr/>
6. <div th:text="${emp.sal ge 800}"></div>
7. <div th:text="${emp.sal } ge 800"></div>
8. <div th:text="${emp.sal ge 800} and ${emp.deptno eq 20}"></div>
9. <div th:text="(${emp.sal }ge 800) or (${emp.deptno } ne 20)"></div>
10. <div th:text="${emp.sal ge 800 or emp.deptno ne 20 }"></div>
在早期的thymeleaf模板引擎框架中 逻辑运算符要写在${}的外边,目前我们2.4.5版本中,可以写在${}里面
4.三目运算符
1. <tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b">
对空值作出处理
<tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b">
2. <td th:text="${i.index}"></td>
3. <td th:text="${i.count}"></td>
4. <td th:text="${i.size}"></td>
5. <td th:text="${i.odd}"></td>
6. <td th:text="${i.even}"></td>
7. <td th:text="${i.first}"></td>
8. <td th:text="${i.last}"></td>
9. <td th:text="${emp.empno}"></td>
10. <td th:text="${emp.ename}"></td>
11. <td th:text="${emp.job}"></td>
12. <td th:text="${emp.mgr} eq null ?老板:${emp.mgr}"></td>
13. <td th:text="${emp.hiredate}"></td>
14. <td th:text="${emp.sal}"></td>
15. <td th:text="${emp.comm} eq null ?0:${emp.comm}"></td>
16. <td th:text="${emp.deptno}"></td>
17. </tr>
四 超链接以及事件
th:href
设置href属性的。取值使用@{}取值
1. <a th:href="@{/getParam(id=1,name='msb')}" >跳转</a>
2. <!-- 获取作用域值-->
3. <a th:href="@{/getParam(name=${stu.name},age=${stu.age})}">跳转二</a>
页面代码
<tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b">
2. <td th:text="${i.index}"></td>
3. <td th:text="${i.count}"></td>
4. <td th:text="${i.size}"></td>
5. <td th:text="${i.odd}"></td>
6. <td th:text="${i.even}"></td>
7. <td th:text="${i.first}"></td>
8. <td th:text="${i.last}"></td>
9. <td th:text="${emp.empno}"></td>
10. <td th:text="${emp.ename}"></td>
11. <td th:text="${emp.job}"></td>
12. <td th:text="${emp.mgr} eq null ?老板:${emp.mgr}"></td>
13. <td th:text="${emp.hiredate}"></td>
14. <td th:text="${emp.sal}"></td>
15. <td th:text="${emp.comm} eq null ?0:${emp.comm}"></td>
16. <td th:text="${emp.deptno}"></td>
17. <td>
18. <a th:href="@{/removeEmp(empno=${emp.empno},ename=${emp.ename})}">删除</a>
19. </td>
20. </tr>
后台controller处理器
1. @Controller
2. public class ThymeleafController {
3.
4. @Autowired
5. private EmpService empService;
6.
7. @RequestMapping("/showAllEmp")
8. public String showEmp(Map<String, Object> map) {
9. List<Emp> empList = empService.findAll();
10. map.put("empList", empList);
11. map.put("emp", empList.get(0));
12. return "showEmp";
13. }
14.
15. @RequestMapping("/removeEmp")
16. public String removeEmp(Integer empno,String ename){
17. boolean success =empService.removeEmp(empno,ename);
18. return "redirect:showAllEmp";
19. }
20. }
th:onclick:给元素绑定事件,单击事件并传递参数
写法1:仅仅支持数字和布尔类型参数的传递,字符串不支持
1. <a href="javascript:viod(0)" th:onclick="'del('+${emp.empno}+')'">删除</a>
写法2:支持数字和文本类型的参数传递
1. <a href="javascript:void(0)" th:onclick="delEmp([[${emp.empno}]],[[${emp.ename}]])">删除</a>
前端代码
1. <table id="empTable" cellpadding="0px" cellspacing="0px">
2. <tr>
3. <th>索引</th>
4. <th>序号</th>
5. <th>总人数</th>
6. <th>偶数索引?</th>
7. <th>奇数索引?</th>
8. <th>第一?</th>
9. <th>最后?</th>
10. <th>工号</th>
11. <th>姓名</th>
12. <th>职务</th>
13. <th>上级</th>
14. <th>入职日期</th>
15. <th>工资</th>
16. <th>补助</th>
17. <th>部门号</th>
18. <th>操作</th>
19. </tr>
20. <tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b">
21. <td th:text="${i.index}"></td>
22. <td th:text="${i.count}"></td>
23. <td th:text="${i.size}"></td>
24. <td th:text="${i.odd}"></td>
25. <td th:text="${i.even}"></td>
26. <td th:text="${i.first}"></td>
27. <td th:text="${i.last}"></td>
28. <td th:text="${emp.empno}"></td>
29. <td th:text="${emp.ename}"></td>
30. <td th:text="${emp.job}"></td>
31. <td th:text="${emp.mgr} eq null ?老板:${emp.mgr}"></td>
32. <td th:text="${emp.hiredate}"></td>
33. <td th:text="${emp.sal}"></td>
34. <td th:text="${emp.comm} eq null ?0:${emp.comm}"></td>
35. <td th:text="${emp.deptno}"></td>
36. <td>
37. <a href="javascript:void(0)" th:onclick="removeEmp([[${emp.empno}]],[[${emp.ename}]])">删除</a>
38. </td>
39. </tr>
40.
41. </table>
42. <script>
43. function removeEmp(empno,ename){
44. var resulet =confirm("确定要删除编号为"+empno+"的"+ename);
45. if(resulet){
46. window.location.href="removeEmp?empno="+empno+"&ename="+ename;
47. }
48. }
49.
50. </script>
五 Thymeleaf内置对象
Thymeleaf提供了一些内置对象,内置对象可直接在模板中使用。这些对象是以#引用的。
使用内置对象的语法
1引用内置对象需要使用#
2大部分内置对象的名称都以s结尾。如:strings、numbers、dates
常见内置对象如下:
- #arrays:数组操作的工具;
- #aggregates:操作数组或集合的工具;
- #bools:判断boolean类型的工具;
- #calendars:类似于#dates,但是是java.util.Calendar类的方法;
- #ctx:上下文对象,可以从中获取所有的thymeleaf内置对象;
- #dates:日期格式化内置对象,具体方法可以参照java.util.Date;
- #numbers: 数字格式化;#strings:字符串格式化,具体方法可以参照String,如startsWith、contains等;
- #objects:参照java.lang.Object;
- #lists:列表操作的工具,参照java.util.List;
- #sets:Set操作工具,参照java.util.Set;#maps:Map操作工具,参照java.util.Map;
- #messages:操作消息的工具。
更多
这里我们着重学习 strings dates numbers和域对象
1.strings对象
2.dates对象
3. numbers对象
#numbers.formatDecimal(numbwe,整数位,整数位千分位标识符,小数位,小数位表示符)
${#numbers.formatDecimal(num,1,'COMMA',2,'POINT')}
显示:99,999,999.99
1:表示整数位至少一位,不足以0补齐,如:num = 0.00,
${#numbers.formatDecimal(num,0,'COMMA',2,'POINT')}则显示 .00
${#numbers.formatDecimal(num,1,'COMMA',2,'POINT')}则显示 0.00
COMMA:','
POINT:‘.’
4.域对象
controller
@RequestMapping("showIndex")
2. public String showIndex(Map<String,Object> map, HttpServletRequest req, HttpSession session){
3. // 向request域放数据
4. req.setAttribute("msg", "requestMessage");
5. // 向session域放数据
6. session.setAttribute("msg", "sessionMessage");
7. // 向application域放数据
8. req.getServletContext().setAttribute("msg", "applicationMessage");
9.
10. // 对象List集合数据
11. List<Emp> empList = empService.findAll();
12. map.put("empList", empList);
13. return "index";
14. }
页面
1. <!DOCTYPE html>
2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
3. <head>
4. <meta charset="UTF-8">
5. <title>Title</title>
6. <style type="text/css">
7. #empTable{
8. width: 80%;
9. border: 1px solid blue;
10. margin: 0px auto;
11. }
12. #empTable th,td{
13. border: 1px solid green;
14. text-align: center;
15. }
16. .a{
17. background-color: antiquewhite;
18. }
19. .b{
20. background-color: gray;
21. }
22. </style>
23. </head>
24. <body>
25. <table id="empTable" cellpadding="0px" cellspacing="0px">
26. <tr>
27. <th>索引</th>
28. <th>序号</th>
29. <th>总人数</th>
30. <th>偶数索引?</th>
31. <th>奇数索引?</th>
32. <th>第一?</th>
33. <th>最后?</th>
34. <th>工号</th>
35. <th>姓名</th>
36. <th>职务</th>
37. <th>上级</th>
38. <th>入职日期</th>
39. <th>入职年</th>
40. <th>入职月</th>
41. <th>入职日</th>
42. <th>工资</th>
43. <th>补助</th>
44. <th>部门号</th>
45. <th>操作</th>
46. </tr>
47. <tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b">
48. <td th:text="${i.index}"></td>
49. <td th:text="${i.count}"></td>
50. <td th:text="${i.size}"></td>
51. <td th:text="${i.odd}"></td>
52. <td th:text="${i.even}"></td>
53. <td th:text="${i.first}"></td>
54. <td th:text="${i.last}"></td>
55. <td th:text="${emp.empno}"></td>
56. <td th:text="${emp.ename}"></td>
57. <td th:text="${emp.job}"></td>
58. <td th:text="${#strings.isEmpty(emp.mgr)}?老板:${emp.mgr}"></td>
59. <td th:text="${#dates.format(emp.hiredate,'yyyy-MM-dd HH:mm:ss')}"></td>
60. <td th:text="${#dates.year(emp.hiredate)}"></td>
61. <td th:text="${#dates.month(emp.hiredate)}"></td>
62. <td th:text="${#dates.day(emp.hiredate)}"></td>
63. <td th:text="${#numbers.formatDecimal(emp.sal,7,'COMMA',2,'POINT')}"></td>
64. <td th:text="${#strings.isEmpty(emp.comm)}?0:${#numbers.formatDecimal(emp.sal,7,'COMMA',2,'POINT')}"></td>
65. <td th:text="${emp.deptno}"></td>
66. <td>
67. <a href="javascript:void(0)" th:onclick="removeEmp([[${emp.empno}]],[[${emp.ename}]])">删除</a>
68. </td>
69. </tr>
70.
71. </table>
72. <script>
73. function removeEmp(empno,ename){
74. var resulet =confirm("确定要删除编号为"+empno+"的"+ename);
75. if(resulet){
76. window.location.href="removeEmp?empno="+empno+"&ename="+ename;
77. }
78. }
79.
80. </script>
81.
82. <hr/>
83. request:<br/>
84. <span th:text="${#httpServletRequest.getAttribute('msg')}"></span><br/>
85. <span th:text="${#request.getAttribute('msg')}"></span><br/>
86. <span th:text="${msg}"></span><br/>
87.
88. session:<br/>
89. <span th:text="${#httpSession.getAttribute('msg')}"></span><br/>
90. <span th:text="${#session.getAttribute('msg')}"></span><br/>
91. <span th:text="${session.msg}"></span><br/>
92.
93. application:<br/>
94. <span th:text="${#servletContext.getAttribute('msg')}"></span><br/>
95. <span th:text="${application.msg}"></span><br/>
96.
97. </body>
98. </html>
六 SpringBoot_模板引擎总结(了解)
jsp
优点:
1、功能强大,可以写java代码
2、支持jsp标签(jsp tag)
3、支持表达式语言(el)
4、官方标准,用户群广,丰富的第三方jsp标签库
缺点:
性能问题。不支持前后端分离
freemarker
FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP。它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 等。
目前企业中:主要用Freemarker做静态页面或是页面展示
优点:
1、不能编写java代码,可以实现严格的mvc分离
2、性能非常不错
3、对jsp标签支持良好
4、内置大量常用功能,使用非常方便
5、宏定义(类似jsp标签)非常方便
6、使用表达式语言
缺点:
1、不是官方标准
2、用户群体和第三方标签库没有jsp多
Thymeleaf
Thymeleaf是个XML/XHTML/HTML5模板引擎,可以用于Web与非Web应用。
Thymeleaf的主要目标在于提供一种可被浏览器正确显示的、格式良好的模板创建方式,因此也可以用作静态建模。你可以使用它创建经过验证的XML与HTML模板。相对于编写逻辑或代码,开发者只需将标签属性添加到模板中即可。接下来,这些标签属性就会在DOM(文档对象模型)上执行预先制定好的逻辑。Thymeleaf的可扩展性也非常棒。你可以使用它定义自己的模板属性集合,这样就可以计算自定义表达式并使用自定义逻辑。这意味着Thymeleaf还可以作为模板引擎框架。
优点:静态html嵌入标签属性,浏览器可以直接打开模板文件,便于前后端联调。springboot官方推荐方案。
缺点:模板必须符合xml规范
VUE: 前后端分离,最多,未来趋势