SpringBoot整合Thymeleaf模板框架 - 图1

前言

Thymeleaf的主要目标是将优雅的自然模板带到开发工作流程中,并将HTML在浏览器中正确显示,并且可以作为静态原型,让开发团队能更容易地协作。Thymeleaf能够处理HTML,XML,JavaScript,CSS甚至纯文本。
长期以来,jsp在视图领域有非常重要的地位,随着时间的变迁,出现了一位新的挑战者:Thymeleaf,Thymeleaf是原生的,不依赖于标签库.它能够在接受原始HTML的地方进行编辑和渲染.因为它没有与Servelet规范耦合,因此Thymeleaf模板能进入jsp所无法涉足的领域。
Thymeleaf在Spring Boot项目中放入到resources/templates中。这个文件夹中的内容是无法通过浏览器URL直接访问的(和WEB-INF效果一样),所有Thymeleaf页面必须先走控制器。

搭建项目

创建一个新的项目,在pom.xml中添加一组 spring-boot-starter-thymeleaf 依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  5. <version>2.4.5</version>
  6. </dependency>
  7. </dependencies>

Thymeleaf默认配置

在springBoot的官方文档指出Thymeleaf的配置地址在 src/resources/temlates/目录下,支持xxxx.html文件进行框架识别
image.pngimage.png

Thymeleaf基础语法

Thymeleaf通过标准变量表达式完成数据的展示和处理
1 标准变量表达式必须依赖标签,不能独立使用
2 标准变量表达式一般在开始标签中,以 th开头
3 语法为:
4 表达式中可以通过${}取出域中的值并放入标签的指定位置
5 ${}在这里不能单独使用,必须在 th:后面的双引号里使用

th:text属性

向HTML标签内部输出信息。
处理器 Controller

  1. @RequestMapping("showIndex")
  2. public String showIndex(Map<String,Object> map){
  3. map.put("msg", "testMessage");
  4. return "index";
  5. }
  1. <!--向span双标签内部添加文本-->
  2. <span th:text="pageMessage"></span> <br/>
  3. <!--从域中根据参数名取出参数值放在双标签中-->
  4. <span th:text="${msg}"></span> <br/>

th:value

表单元素,设置HTML标签中表单元素value属性时使用。

  1. <!--向input标签中的value属性赋值-->
  2. <input type="text" th:value="pageMessage"/>
  3. <!--从域中根据参数名取出参数值 向input标签中的value属性赋值-->
  4. <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代码

  1. @Controller
  2. public class ThymeleafController {
  3. @Autowired
  4. private EmpService empService;
  5. @RequestMapping("/showEmp")
  6. public String showEmp(Map<String, Object> map) {
  7. List<Emp> empList = empService.findAll();
  8. map.put("empList", empList);
  9. map.put("emp", empList.get(0));
  10. return "showEmp";
  11. }

页面模板代码

  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. <span th:if="${empList}!=null">
  20. <span th:if="${empList.size()} ne 0">
  21. 工号:<span th:text="${empList[0].empno}"></span><br/>
  22. 姓名:<span th:text="${empList[0].ename}"></span><br/>
  23. 职务:<span th:text="${empList[0].job}"></span><br/>
  24. 上级:<span th:text="${empList[0].mgr}"></span><br/>
  25. 入职日期:<span th:text="${empList[0].hiredate}"></span><br/>
  26. 工资:<span th:text="${empList[0].sal}"></span><br/>
  27. 补助:<span th:text="${empList[0].comm}"></span><br/>
  28. 部门号:<span th:text="${empList[0].deptno}"></span><br/>
  29. </span>
  30. </span>
  31. <table id="empTable" cellpadding="0px" cellspacing="0px">
  32. <tr>
  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. <th>补助</th>
  47. <th>部门号</th>
  48. </tr>
  49. <tr th:each="emp,i:${empList}">
  50. <td th:text="${i.index}"></td>
  51. <td th:text="${i.count}"></td>
  52. <td th:text="${i.size}"></td>
  53. <td th:text="${i.odd}"></td>
  54. <td th:text="${i.even}"></td>
  55. <td th:text="${i.first}"></td>
  56. <td th:text="${i.last}"></td>
  57. <td th:text="${emp.empno}"></td>
  58. <td th:text="${emp.ename}"></td>
  59. <td th:text="${emp.job}"></td>
  60. <td th:text="${emp.mgr}"></td>
  61. <td th:text="${emp.hiredate}"></td>
  62. <td th:text="${emp.sal}"></td>
  63. <td th:text="${emp.comm}"></td>
  64. <td th:text="${emp.deptno}"></td>
  65. </tr>
  66. </table>
  67. </body>
  68. </html>

算术运算符

算术运算:+,-,*,/,%

  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>

关系运算符

1 gt: great than(大于)>
2 ge: great equal(大于等于)>=
3 eq: equal(等于)==
4 lt: less than(小于)<
5 le: less equal(小于等于)<=
6 ne: not equal(不等于)!=

逻辑运算符

&& 或 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版本中,可以写在${}里面

三目运算符

和常用的java中的三目运算符是一样的,但在html中使用 th:class=””的方式去取值并进行值比较。

  1. 例:<tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b">

对空值做处理

使用三目运算符和关系运算符来组合做空空值判断

  1. 例:<td th:text="${emp.mgr} eq null ?老板:${emp.mgr}"></td>

th:href

设置a标签中的href属性,取值使用@{}取值

  1. <a th:href="@{/getParam(id=1,name='msb')}" >跳转</a>
  2. <!-- 获取作用域值-->
  3. <a th:href="@{/getParam(name=${stu.name},age=${stu.age})}">跳转二</a>

页面代码:

  1. <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. @Autowired
  4. private EmpService empService;
  5. @RequestMapping("/showAllEmp")
  6. public String showEmp(Map<String, Object> map) {
  7. List<Emp> empList = empService.findAll();
  8. map.put("empList", empList);
  9. map.put("emp", empList.get(0));
  10. return "showEmp";
  11. }
  12. @RequestMapping("/removeEmp")
  13. public String removeEmp(Integer empno,String ename){
  14. boolean success =empService.removeEmp(empno,ename);
  15. return "redirect:showAllEmp";
  16. }
  17. }

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. </table>
  41. <script>
  42. function removeEmp(empno,ename){
  43. var resulet =confirm("确定要删除编号为"+empno+"的"+ename);
  44. if(resulet){
  45. window.location.href="removeEmp?empno="+empno+"&ename="+ename;
  46. }
  47. }
  48. </script>

内置对象API

Thymeleaf提供了一些内置对象,内置对象可直接在模板中使用。这些对象是以#引用的。
使用内置对象的语法
1引用内置对象需要使用#
2大部分内置对象的名称都以s结尾。如:strings、numbers、dates
3常见内置对象如下
#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:操作消息的工具。
更多
image.png
官方文档:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
image.png
参考链接:https://blog.csdn.net/lianghecai52171314/article/details/106394943/?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.opensearchhbase&spm=1001.2101.3001.4242.1

实例

  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>IT Thymeleaf 内置方法</title>
  6. </head>
  7. <body>
  8. <h3>#strings </h3>
  9. <div th:if="${not #strings.isEmpty(itStr)}" >
  10. <p>Old Str : <span th:text="${itStr}"/></p>
  11. <p>toUpperCase : <span th:text="${#strings.toUpperCase(itStr)}"/></p>
  12. <p>toLowerCase : <span th:text="${#strings.toLowerCase(itStr)}"/></p>
  13. <p>equals : <span th:text="${#strings.equals(itStr, 'helloworld')}"/></p>
  14. <p>equalsIgnoreCase : <span th:text="${#strings.equalsIgnoreCase(itStr, 'helloworld')}"/></p>
  15. <p>indexOf : <span th:text="${#strings.indexOf(itStr, 'r')}"/></p>
  16. <p>substring : <span th:text="${#strings.substring(itStr, 2, 8)}"/></p>
  17. <p>replace : <span th:text="${#strings.replace(itStr, 'or', 'IT')}"/></p>
  18. <p>startsWith : <span th:text="${#strings.startsWith(itStr, 'he')}"/></p>
  19. <p>contains : <span th:text="${#strings.contains(itStr, 'ow')}"/></p>
  20. </div>
  21. <h3>#numbers </h3>
  22. <div>
  23. <p>formatDecimal 整数部分随意,小数点后保留两位,四舍五入: <span th:text="${#numbers.formatDecimal(itNum, 0, 2)}"/></p>
  24. <p>formatDecimal 整数部分保留五位数,小数点后保留两位,四舍五入: <span th:text="${#numbers.formatDecimal(itNum, 5, 2)}"/></p>
  25. </div>
  26. <h3>#bools </h3>
  27. <div th:if="${#bools.isTrue(itBool)}">
  28. <p th:text="${itBool}"></p>
  29. </div>
  30. <h3>#arrays </h3>
  31. <div th:if="${not #arrays.isEmpty(itArray)}">
  32. <p>length : <span th:text="${#arrays.length(itArray)}"/></p>
  33. <p>contains : <span th:text="${#arrays.contains(itArray, 5)}"/></p>
  34. <p>containsAll : <span th:text="${#arrays.containsAll(itArray, itArray)}"/></p>
  35. </div>
  36. <h3>#lists </h3>
  37. <div th:if="${not #lists.isEmpty(itList)}">
  38. <p>size : <span th:text="${#lists.size(itList)}"/></p>
  39. <p>contains : <span th:text="${#lists.contains(itList, 0)}"/></p>
  40. <p>sort : <span th:text="${#lists.sort(itList)}"/></p>
  41. </div>
  42. <h3>#maps </h3>
  43. <div th:if="${not #maps.isEmpty(itMap)}">
  44. <p>size : <span th:text="${#maps.size(itMap)}"/></p>
  45. <p>containsKey : <span th:text="${#maps.containsKey(itMap, 'thName')}"/></p>
  46. <p>containsValue : <span th:text="${#maps.containsValue(itMap, '#maps')}"/></p>
  47. </div>
  48. <h3>#dates </h3>
  49. <div>
  50. <p>format : <span th:text="${#dates.format(itDate)}"/></p>
  51. <p>custom format : <span th:text="${#dates.format(itDate, 'yyyy-MM-dd HH:mm:ss')}"/></p>
  52. <p>day : <span th:text="${#dates.day(itDate)}"/></p>
  53. <p>month : <span th:text="${#dates.month(itDate)}"/></p>
  54. <p>monthName : <span th:text="${#dates.monthName(itDate)}"/></p>
  55. <p>year : <span th:text="${#dates.year(itDate)}"/></p>
  56. <p>dayOfWeekName : <span th:text="${#dates.dayOfWeekName(itDate)}"/></p>
  57. <p>hour : <span th:text="${#dates.hour(itDate)}"/></p>
  58. <p>minute : <span th:text="${#dates.minute(itDate)}"/></p>
  59. <p>second : <span th:text="${#dates.second(itDate)}"/></p>
  60. <p>createNow : <span th:text="${#dates.createNow()}"/></p>
  61. </div>
  62. </body>
  63. </html>
  1. 第二步:对应的Controller
  2. @RequestMapping("demo3")
  3. public String demo3(ModelMap modelMap) {
  4. modelMap.put("itStr", "HelloWorld");
  5. modelMap.put("itNum", 888.888D);
  6. modelMap.put("itBool", true);
  7. modelMap.put("itArray", new Integer[]{1,2,3,4});
  8. modelMap.put("itList", Arrays.asList(1,3,2,4,0));
  9. Map itMap = new HashMap();
  10. itMap.put("thName", "${#...}");
  11. itMap.put("desc", "变量表达式内置方法");
  12. modelMap.put("itMap", itMap);
  13. modelMap.put("itDate", new Date());
  14. return "demo3";
  15. }

strings对象

  1. /*
  2. * Null-safe toString()
  3. */
  4. ${#strings.toString(obj)} // 也可以是 array*、list* 或 set*
  5. /*
  6. * 检查String是否为空(或null)。在检查之前执行trim()操作也同样适用于数组、列表或集合
  7. */
  8. ${#strings.isEmpty(name)}
  9. ${#strings.arrayIsEmpty(nameArr)}
  10. ${#strings.listIsEmpty(nameList)}
  11. ${#strings.setIsEmpty(nameSet)}
  12. /*
  13. * 对字符串执行“isEmpty()”检查, 如果为false则返回它, 如果为true则默认为另一个指定的字符串。
  14. * 也同样适用于数组、列表或集合
  15. */
  16. ${#strings.defaultString(text,default)}
  17. ${#strings.arrayDefaultString(textArr,default)}
  18. ${#strings.listDefaultString(textList,default)}
  19. ${#strings.setDefaultString(textSet,default)}
  20. /*
  21. * 检查字符串中是否包含片段,比如 ${#strings.containsIgnoreCase(user.name,'kang')}
  22. * 也同样适用于数组、列表或集合
  23. */
  24. ${#strings.contains(name,'ez')} // 也可以是 array*、list* 或 set*
  25. ${#strings.containsIgnoreCase(name,'ez')} // 也可以是 array*、list* 或 set*
  26. /*
  27. * 检查字符串是否以片段开始或结束
  28. * 也同样适用于数组、列表或集合
  29. */
  30. ${#strings.startsWith(name,'Don')} // 也可以是 array*、list* 或 set*
  31. ${#strings.endsWith(name,endingFragment)} // 也可以是 array*、list* 或 set*
  32. /*
  33. * 子串相关操作
  34. * 也同样适用于数组、列表或集合
  35. */
  36. ${#strings.indexOf(name,frag)} // 也可以是 array*、list* 或 set*
  37. ${#strings.substring(name,3,5)} // 也可以是 array*、list* 或 set*
  38. ${#strings.substringAfter(name,prefix)} // 也可以是 array*、list* 或 set*
  39. ${#strings.substringBefore(name,suffix)} // 也可以是 array*、list* 或 set*
  40. ${#strings.replace(name,'las','ler')} // 也可以是 array*、list* 或 set*
  41. /*
  42. * 附加和前置
  43. * 也同样适用于数组、列表或集合
  44. */
  45. ${#strings.prepend(str,prefix)} // 也可以是 array*、list* 或 set*
  46. ${#strings.append(str,suffix)} // 也可以是 array*、list* 或 set*
  47. /*
  48. * 大小写转换
  49. * 也同样适用于数组、列表或集合
  50. */
  51. ${#strings.toUpperCase(name)} // 也可以是 array*、list* 或 set*
  52. ${#strings.toLowerCase(name)} // 也可以是 array*、list* 或 set*
  53. /*
  54. * 拆分和拼接
  55. */
  56. ${#strings.arrayJoin(namesArray,',')}
  57. ${#strings.listJoin(namesList,',')}
  58. ${#strings.setJoin(namesSet,',')}
  59. ${#strings.arraySplit(namesStr,',')} // 返回String []
  60. ${#strings.listSplit(namesStr,',')} // 返回List<String>
  61. ${#strings.setSplit(namesStr,',')} // 返回Set<String>
  62. /*
  63. * Trim
  64. * 也同样适用于数组、列表或集合
  65. */
  66. ${#strings.trim(str)} // 也可以是 array*、list* 或 set*
  67. /*
  68. * 计算长度
  69. * 也同样适用于数组、列表或集合
  70. */
  71. ${#strings.length(str)} // 也可以是 array*、list* 或 set*
  72. /*
  73. * 缩写文本, 使其最大大小为n。如果文本较大, 它将被剪辑并在末尾附加“...”
  74. * 也同样适用于数组、列表或集合
  75. */
  76. ${#strings.abbreviate(str,10)} // 也可以是 array*、list* 或 set*
  77. /*
  78. * 将第一个字符转换为大写(反之亦然)
  79. */
  80. ${#strings.capitalize(str)} // 也可以是 array*、list* 或 set*
  81. ${#strings.unCapitalize(str)} // 也可以是 array*、list* 或 set*
  82. /*
  83. * 将每个单词的第一个字符转换为大写
  84. */
  85. ${#strings.capitalizeWords(str)} // 也可以是 array*、list* 或 set*
  86. ${#strings.capitalizeWords(str,delimiters)} // 也可以是 array*、list* 或 set*
  87. /*
  88. * 转义字符串
  89. */
  90. ${#strings.escapeXml(str)} // 也可以是 array*、list* 或 set*
  91. ${#strings.escapeJava(str)} // 也可以是 array*、list* 或 set*
  92. ${#strings.escapeJavaScript(str)} // 也可以是 array*、list* 或 set*
  93. ${#strings.unescapeJava(str)} // 也可以是 array*、list* 或 set*
  94. ${#strings.unescapeJavaScript(str)} // 也可以是 array*、list* 或 set*
  95. /*
  96. * 空安全比较和连接
  97. */
  98. ${#strings.equals(first, second)}
  99. ${#strings.equalsIgnoreCase(first, second)}
  100. ${#strings.concat(values...)}
  101. ${#strings.concatReplaceNulls(nullValue, values...)}
  102. /*
  103. * 随机数
  104. */
  105. ${#strings.randomAlphanumeric(count)}

dates对象

/*
* 使用标准区域设置格式格式化日期
* 也同样适用于数组、列表或集合
*/
${#dates.format(date)}
${#dates.arrayFormat(datesArray)}
${#dates.listFormat(datesList)}
${#dates.setFormat(datesSet)}

/*
* 使用ISO8601格式格式化日期
* 也同样适用于数组、列表或集合
*/
${#dates.formatISO(date)}
${#dates.arrayFormatISO(datesArray)}
${#dates.listFormatISO(datesList)}
${#dates.setFormatISO(datesSet)}

/*
* 使用指定的格式格式化日期,比如 ${#dates.format(date,'yyyy-MM-dd HH:mm:ss')}
* 也同样适用于数组、列表或集合
*/
${#dates.format(date, 'dd/MMM/yyyy HH:mm')}
${#dates.arrayFormat(datesArray, 'dd/MMM/yyyy HH:mm')}
${#dates.listFormat(datesList, 'dd/MMM/yyyy HH:mm')}
${#dates.setFormat(datesSet, 'dd/MMM/yyyy HH:mm')}

/*
* 获取日期属性
* 也同样适用于数组、列表或集合
*/
${#dates.day(date)} // 也可以是 arrayDay(...), listDay(...)之类的
${#dates.month(date)} // 也可以是 arrayMonth(...), listMonth(...)之类的
${#dates.monthName(date)} // 也可以是 arrayMonthName(...), listMonthName(...)之类的
${#dates.monthNameShort(date)} // 也可以是 arrayMonthNameShort(...), listMonthNameShort(...)之类的
${#dates.year(date)} // 也可以是 arrayYear(...), listYear(...)之类的
${#dates.dayOfWeek(date)} // 也可以是 arrayDayOfWeek(...), listDayOfWeek(...)之类的
${#dates.dayOfWeekName(date)} // 也可以是 arrayDayOfWeekName(...), listDayOfWeekName(...)之类的
${#dates.dayOfWeekNameShort(date)} // 也可以是 arrayDayOfWeekNameShort(...), listDayOfWeekNameShort(...)之类的
${#dates.hour(date)} // 也可以是 arrayHour(...), listHour(...)之类的
${#dates.minute(date)} // 也可以是 arrayMinute(...), listMinute(...)之类的
${#dates.second(date)} // 也可以是 arraySecond(...), listSecond(...)之类的
${#dates.millisecond(date)} // 也可以是 arrayMillisecond(...), listMillisecond(...)之类的

/*
* 根据year,month,day创建日期(java.util.Date)对象,比如 ${#dates.create('2008','08','08')}
*/
${#dates.create(year,month,day)}
${#dates.create(year,month,day,hour,minute)}
${#dates.create(year,month,day,hour,minute,second)}
${#dates.create(year,month,day,hour,minute,second,millisecond)}

/*
* 创建当前日期和时间创建日期(java.util.Date)对象,比如 ${#dates.format(#dates.createNow(),'yyyy-MM-dd HH:mm:ss')}
*/
${#dates.createNow()}

${#dates.createNowForTimeZone()}

/*
* 创建当前日期创建一个日期(java.util.Date)对象(时间设置为00:00)
*/
${#dates.createToday()}

${#dates.createTodayForTimeZone()}

Calendars对象

/*
* 使用标准区域设置格式格式化日历
* 也同样适用于数组、列表或集合
*/
${#calendars.format(cal)}
${#calendars.arrayFormat(calArray)}
${#calendars.listFormat(calList)}
${#calendars.setFormat(calSet)}

/*
* 使用ISO8601格式格式化日历
* 也同样适用于数组、列表或集合
*/
${#calendars.formatISO(cal)}
${#calendars.arrayFormatISO(calArray)}
${#calendars.listFormatISO(calList)}
${#calendars.setFormatISO(calSet)}

/*
* 使用指定的格式格式化日历
* 也同样适用于数组、列表或集合
*/
${#calendars.format(cal, 'dd/MMM/yyyy HH:mm')}
${#calendars.arrayFormat(calArray, 'dd/MMM/yyyy HH:mm')}
${#calendars.listFormat(calList, 'dd/MMM/yyyy HH:mm')}
${#calendars.setFormat(calSet, 'dd/MMM/yyyy HH:mm')}

/*
* 获取日历属性
* 也同样适用于数组、列表或集合
*/
${#calendars.day(date)} // 也可以是 arrayDay(...), listDay(...)之类的
${#calendars.month(date)} // 也可以是 arrayMonth(...), listMonth(...)之类的
${#calendars.monthName(date)} // 也可以是 arrayMonthName(...), listMonthName(...)之类的
${#calendars.monthNameShort(date)} // 也可以是 arrayMonthNameShort(...), listMonthNameShort(...)之类的
${#calendars.year(date)} // 也可以是 arrayYear(...), listYear(...)之类的
${#calendars.dayOfWeek(date)} // 也可以是 arrayDayOfWeek(...), listDayOfWeek(...)之类的
${#calendars.dayOfWeekName(date)} // 也可以是 arrayDayOfWeekName(...), listDayOfWeekName(...)之类的
${#calendars.dayOfWeekNameShort(date)} // 也可以是 arrayDayOfWeekNameShort(...), listDayOfWeekNameShort(...)之类的
${#calendars.hour(date)} // 也可以是 arrayHour(...), listHour(...)之类的
${#calendars.minute(date)} // 也可以是 arrayMinute(...), listMinute(...)之类的
${#calendars.second(date)} // 也可以是 arraySecond(...), listSecond(...)之类的
${#calendars.millisecond(date)} // 也可以是 arrayMillisecond(...), listMillisecond(...)之类的

/*
* 从其组件创建日历(java.util.Calendar)对象
*/
${#calendars.create(year,month,day)}
${#calendars.create(year,month,day,hour,minute)}
${#calendars.create(year,month,day,hour,minute,second)}
${#calendars.create(year,month,day,hour,minute,second,millisecond)}

${#calendars.createForTimeZone(year,month,day,timeZone)}
${#calendars.createForTimeZone(year,month,day,hour,minute,timeZone)}
${#calendars.createForTimeZone(year,month,day,hour,minute,second,timeZone)}
${#calendars.createForTimeZone(year,month,day,hour,minute,second,millisecond,timeZone)}

/*
* 为当前日期和时间创建一个日历(java.util.Calendar)对象
*/
${#calendars.createNow()}

${#calendars.createNowForTimeZone()}

/*
* 为当前日期创建日历(java.util.Calendar)对象(时间设置为00:00)
*/
${#calendars.createToday()}

${#calendars.createTodayForTimeZone()}

numbers对象

/*
* ==========================
* 格式化整数
* ==========================
*/

/*
* 设置最小整数位数。
* 也同样适用于数组、列表或集合
*/
${#numbers.formatInteger(num,3)}
${#numbers.arrayFormatInteger(numArray,3)}
${#numbers.listFormatInteger(numList,3)}
${#numbers.setFormatInteger(numSet,3)}


/*
* 设置最小整数位数和千位分隔符:
* 'POINT'、'COMMA'、'WHITESPACE'、'NONE' 或 'DEFAULT'(根据本地化)。
* 也同样适用于数组、列表或集合
*/
${#numbers.formatInteger(num,3,'POINT')}
${#numbers.arrayFormatInteger(numArray,3,'POINT')}
${#numbers.listFormatInteger(numList,3,'POINT')}
${#numbers.setFormatInteger(numSet,3,'POINT')}


/*
* ==========================
* 格式化十进制数
* ==========================
*/

/*
* 设置最小整数数字和(精确的)十进制数字。
* 也同样适用于数组、列表或集合
*/
${#numbers.formatDecimal(num,3,2)}
${#numbers.arrayFormatDecimal(numArray,3,2)}
${#numbers.listFormatDecimal(numList,3,2)}
${#numbers.setFormatDecimal(numSet,3,2)}

/*
* 设置最小整数数字和(精确的)小数位数, 以及小数分隔符。
* 也同样适用于数组、列表或集合
*/
${#numbers.formatDecimal(num,3,2,'COMMA')}
${#numbers.arrayFormatDecimal(numArray,3,2,'COMMA')}
${#numbers.listFormatDecimal(numList,3,2,'COMMA')}
${#numbers.setFormatDecimal(numSet,3,2,'COMMA')}

/*
* 设置最小整数数字和(精确的)十进制数字, 以及千位和十进制分隔符。
* 也同样适用于数组、列表或集合
*/
${#numbers.formatDecimal(num,3,'POINT',2,'COMMA')}
${#numbers.arrayFormatDecimal(numArray,3,'POINT',2,'COMMA')}
${#numbers.listFormatDecimal(numList,3,'POINT',2,'COMMA')}
${#numbers.setFormatDecimal(numSet,3,'POINT',2,'COMMA')}

/*
* ==========================
* 实用方法
* ==========================
*/

/*
* 创建一个从x到y的整数序列(数组)
*/
${#numbers.sequence(from,to)}
${#numbers.sequence(from,to,step)}

实例:

<p th:utext="${#numbers.formatInteger(0.1024,3)}"></p>
<p th:utext="${#numbers.formatInteger(1.024,3)}"></p>
<p th:utext="${#numbers.formatInteger(10.24,3)}"></p>
<p th:utext="${#numbers.formatInteger(102.4,3)}"></p>

<br><br>

<p th:utext="${#numbers.formatInteger(1.024,2,'POINT')}"></p>
<p th:utext="${#numbers.formatInteger(1024,3,'POINT')}"></p>
<p th:utext="${#numbers.formatInteger(1024,10,'POINT')}"></p>

<p th:utext="${#numbers.formatInteger(1.024,2,'COMMA')}"></p>
<p th:utext="${#numbers.formatInteger(1024,3,'COMMA')}"></p>
<p th:utext="${#numbers.formatInteger(1024,10,'COMMA')}"></p>

<p th:utext="${#numbers.formatInteger(1.024,2,'WHITESPACE')}"></p>
<p th:utext="${#numbers.formatInteger(1024,3,'WHITESPACE')}"></p>
<p th:utext="${#numbers.formatInteger(1024,10,'WHITESPACE')}"></p>

objects对象

/*
* 当obj不为空时,返回obj,否则返回default默认值
* 其同样适用于数组、列表或集合
*/
${#objects.nullSafe(obj,default)}
${#objects.arrayNullSafe(objArray,default)}
${#objects.listNullSafe(objList,default)}
${#objects.setNullSafe(objSet,default)}

bools对象

/*
* 评估条件, 类似于 th:if 标签
* 也同样适用于数组、列表或集合
*/
${#bools.isTrue(obj)}
${#bools.arrayIsTrue(objArray)}
${#bools.listIsTrue(objList)}
${#bools.setIsTrue(objSet)}

/*
* 用否定来评估条件
* 也同样适用于数组、列表或集合
*/
${#bools.isFalse(cond)}
${#bools.arrayIsFalse(condArray)}
${#bools.listIsFalse(condList)}
${#bools.setIsFalse(condSet)}

/*
* 评估条件并执行与操作
* 接收数组、列表或集合作为参数
*/
${#bools.arrayAnd(condArray)}
${#bools.listAnd(condList)}
${#bools.setAnd(condSet)}

/*
* 评估条件并执行或操作
* 接收数组、列表或集合作为参数
*/
${#bools.arrayOr(condArray)}
${#bools.listOr(condList)}
${#bools.setOr(condSet)}

arrays对象

/*
* 转换为数组, 试图推断数组组件类。注意, 如果结果数组为空, 或者目标对象的元素不是全部相同的类, 则
* 此方法将返回Object []。
*/
${#arrays.toArray(object)}

/*
* 转换为指定组件类的数组。
*/
${#arrays.toStringArray(object)}
${#arrays.toIntegerArray(object)}
${#arrays.toLongArray(object)}
${#arrays.toDoubleArray(object)}
${#arrays.toFloatArray(object)}
${#arrays.toBooleanArray(object)}

/*
* 计算数组长度
*/
${#arrays.length(array)}

/*
* 检查数组是否为空
*/
${#arrays.isEmpty(array)}

/*
* 检查数组中是否包含元素或元素集合
*/
${#arrays.contains(array, element)}
${#arrays.containsAll(array, elements)}

lists对象

/*
* 转化为 list
*/
${#lists.toList(object)}

/*
* 计算大小
*/
${#lists.size(list)}

/*
*/
${#lists.isEmpty(list)}

/*
* 检查list中是否包含元素或元素集合
*/
${#lists.contains(list, element)}
${#lists.containsAll(list, elements)}

/*
* 排序给定列表的副本。列表的成员必须
* 实现comparable, 或者必须定义comparator。
*/
${#lists.sort(list)}
${#lists.sort(list, comparator)}

sets对象

/*
* 转化为 to set
*/
${#sets.toSet(object)}

/*
* 计算大小
*/
${#sets.size(set)}

/*
* 检查set是否为empty
*/
${#sets.isEmpty(set)}

/*
* 检查set中是否包含元素或元素集合
*/
${#sets.contains(set, element)}
${#sets.containsAll(set, elements)}

maps对象

/*
* 计算大小
*/
${#maps.size(map)}

/*
* 检查map是否为空
*/
${#maps.isEmpty(map)}

/*
* 检查map中是否包含key/s或value/s
*/
${#maps.containsKey(map, key)}
${#maps.containsAllKeys(map, keys)}
${#maps.containsValue(map, value)}
${#maps.containsAllValues(map, value)}

aggregates对象

/*
* 计算总和。如果数组或集合为空,则返回null
*/
${#aggregates.sum(array)}
${#aggregates.sum(collection)}
/*
* 计算平均值。如果数组或集合为空,则返回null
*/
${#aggregates.avg(array)}
${#aggregates.avg(collection)}

messages对象

/*
* 获取外部化消息。可以接收单个键,一个键加上参数,
* 或者一个数组/列表/密钥集(在这种情况下,它将返回一个数组/列表/外部化消息集)。
* 如果未找到消息,则返回默认消息(如“??msgKey??”)。
*/
${#messages.msg('msgKey')}
${#messages.msg('msgKey', param1)}
${#messages.msg('msgKey', param1, param2)}
${#messages.msg('msgKey', param1, param2, param3)}
${#messages.msgWithParams('msgKey', new Object[] {param1, param2, param3, param4})}
${#messages.arrayMsg(messageKeyArray)}
${#messages.listMsg(messageKeyList)}
${#messages.setMsg(messageKeySet)}
/*
* 获取外部化消息或null。如果找不到指定密钥的消息,则返回Null而不是默认消息。
*/
${#messages.msgOrNull('msgKey')}
${#messages.msgOrNull('msgKey', param1)}
${#messages.msgOrNull('msgKey', param1, param2)}
${#messages.msgOrNull('msgKey', param1, param2, param3)}
${#messages.msgOrNullWithParams('msgKey', new Object[] {param1, param2, param3, param4})}
${#messages.arrayMsgOrNull(messageKeyArray)}
${#messages.listMsgOrNull(messageKeyList)}
${#messages.setMsgOrNull(messageKeySet)}

ids对象

/*
* 通常在th:id属性中使用,用于将计数器附加到id属性值,以便它即使在迭代过程中也保持唯一。
*/
${#ids.seq('someId')}
/*
* 通常用于th:for<label>标记中的属性,因此这些标签可以引用通过#id生成的id。序号(…)作用
*
* 取决于<label>是在带有#id的元素之前还是之后。序号(…)函数,
* 则应调用“next”(标签位于“seq”之前)或“prev”函数(标签位于“seq”之后)。
*/
${#ids.next('someId')}
${#ids.prev('someId')}