SpringBoot整合Thymeleaf基于SpringBoot2.X版本
一、现在不都前后端分离了?为什么要用Thymeleaf模板引擎?
为什么开始用Thymeleaf模板引擎?不是使用jsp呢? 首先前端交给我们的页面,是html页面,如果是我们之前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。jsp支持非常强大的功能,包括能写Java代码。
但是呢,SpringBoot项目是以jar的方式,不是war方式,而且SpringBoot用的还是嵌入式的Tomcat,所以呢,他现在默认是不支持jsp的。
那不支持jsp,如果我们直接用纯静态页面的方式,那给我们开发会带来非常大的麻烦,那怎么办呢,SpringBoot推荐使用模板引擎。模板引擎有很多种,比如Thymeleaf、Velocity、FreeMarker,不过思想都是一致的,springboot推荐使用Thymeleaf,当然基本上程序员用的都是Thymeleaf模板引擎,在业界Thymeleaf模板引擎是业界的一致好评。
现在不都前后端分离了么?Vue这么流行为什么还需要学习thymeleaf? 虽然现在慢慢在流行前后端分离开发,但是还是有一些的公司依旧在做前后端不分离的开发,而在前后端不分的开发中,我们就会需要后端页面模板引擎(即使前后端分离,也会在一些场景下需要使用页面模板,举个典型的栗子:邮件发送模板)。
二、SpringBoot整合Thymeleaf环境搭建
2.1.创建springboot项目

设置项目名称和包名

选择spring web项目,同时注意springboot的版本

2.2.在pom.xml中导入依赖
注意其中最为主要的就是 thymeleaf 模板,由于后续需要进行数据库连接操作,相关依赖也就一并导入导入了
<!-- 引入thymeleaf模板引擎依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>2.7.5</version> </dependency> <!--mybatis依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> <!--MySQL数据库连接的依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> <!--lombok插件--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>provided</scope> </dependency> <!-- pagehelper分页依赖 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.12</version> </dependency> <!--添加druid连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
2.3.在resources目录下创建配置文件
2.3.1.新增 application.yml 文件,内容如下:
关于Thymeleaf 默认配置了前缀和后缀(已经不需要我们特殊设置了),源码如下图:

配置文件内容如下:
spring: datasource: # 使用阿里的Druid连接池 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver # 填写你数据库的url、登录名、密码和数据库名 url: jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai username: test password: 123456 druid: # 连接池的配置信息 # 初始化大小,最小,最大 initial-size: 5 min-idle: 5 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false # 打开PSCache,并且指定每个连接上PSCache的大小 poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 filters: stat,wall,slf4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000 # 配置DruidStatFilter web-stat-filter: enabled: true url-pattern: "/*" exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*" # 配置DruidStatViewServlet stat-view-servlet: url-pattern: "/druid/*" # IP白名单(没有配置或者为空,则允许所有访问) allow: 127.0.0.1,192.168.8.109 # IP黑名单 (存在共同时,deny优先于allow) deny: 192.168.1.188 # 禁用HTML页面上的“Reset All”功能 reset-enable: false # 登录名 login-username: admin # 登录密码 login-password: 123456 #thymeleaf会自动设置前缀和后缀,这里就不需要手动添加了 # thymeleaf: # suffix: # prefix: mybatis: mapper-locations: classpath:mybatis/*.xml type-aliases-package: com.augus.pojo server: servlet: context-path: /springboot08 port: 8080
2.3.2创建 logback.xml 引入日志文件,方便调试
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--> <property name="LOG_HOME" value="${catalina.base}/logs/" /> <!-- 控制台输出 --> <appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender"> <!-- 日志输出格式 --> <layout class="ch.qos.logback.classic.PatternLayout"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n </pattern> </layout> </appender> <!-- 按照每天生成日志文件 --> <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日志文件输出的文件名--> <FileNamePattern>${LOG_HOME}/server.%d{yyyy-MM-dd}.log</FileNamePattern> <MaxHistory>30</MaxHistory> </rollingPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n </pattern> </layout> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!-- 日志输出级别 --> <root level="debug"> <appender-ref ref="Stdout" /> <appender-ref ref="RollingFile" /> </root> <logger name="com.augus.mapper" level="DEBUG"></logger> <!--日志异步到数据库 --> <!--<appender name="DB" class="ch.qos.logback.classic.db.DBAppender"> 日志异步到数据库 <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource"> 连接池 <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource"> <driverClass>com.mysql.jdbc.Driver</driverClass> <url>jdbc:mysql://127.0.0.1:3306/databaseName</url> <user>root</user> <password>root</password> </dataSource> </connectionSource> </appender> --> </configuration>
2.4.在resources下的templates中创建html文件
常见名为:show.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> this is show.html <div th:text="${name}"></div> </body> </html>
注意:
需要在html开始标签中引入命名空间:xmlns:th="http://www.thymeleaf.org"
2.5.在com.augus包中创建controller
在下面创建控制器:ShowController内容如下:
package com.augus.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import java.util.Map; @Controller public class ShowController { @RequestMapping("/show") public String freeMarkerShow(Map<String, Object> map){ //向前端传递数据 map.put("name", "梦特娇"); //返回模块文件名称 return "show"; } }
2.6.测试
启动项目:浏览器访问 http://localhost:8080/springboot08/show,如下图所示表示环境搭建成功

三、标准变量表达式
Thymeleaf通过标准变量表达式完成数据的展示和处理
- 标准变量表达式必须依赖标签,不能独立使用
- 标准变量表达式一般在开始标签中,以 th开头
- 语法为: <tag th:***="${key}" ></tag>
- 表达式中可以通过${}取出域中的值并放入标签的指定位置
- ${}在这里不能单独使用,必须在 th:后面的双引号里使用
要使用thymeleaf, 就需要进入命名空间,修改html页面中<html>标签为:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
3.1. th:text属性
th:text可以实现向HTML标签内部输出信息的效果,例如之前项目搭建时候的案例。
controller中ShowController 代码如下
package com.augus.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import java.util.Map; @Controller public class ShowController { @RequestMapping("/show") public String freeMarkerShow(Map<String, Object> map){ //向前端传递数据 map.put("name", "梦特娇"); //返回模块文件名称 return "show"; } }
页面代码:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
this is show.html
<div th:text="${name}"></div>
</body>
</html>
3.2. th:value
th:value的方式可以实现给表单元素,设置HTML标签中表单元素value属性时使用。
<!--向input标签中的value属性赋值-->
<input type="text" th:value="pageMessage"/>
<!--从域中根据参数名取出参数值 向input标签中的value属性赋值-->
<input type="text" th:value="${msg}"/>
3.3. th:if
可以实现根据内容判断传值的效果
<!-- 如果username的值是limin则span标签的文本信息则显示boss,否则显示emp -->
<span th:if="${username}=='limin'?boss:emp"></span>
3.4. 循环遍历.th:each
例如:以empList 遍历输出。
th:each="emp,i :${empList}" 其中i表示迭代状态。
- index:当前迭代器的索引 从0开始
- count:当前迭代对象的计数 从1开始
- size:被迭代对象的长度
- even(奇数) / odd(偶数):布尔值,当前循环是否是奇数/偶数 从0开始
- first:布尔值,当前循环的是否是第一条,如果是返回true否则返回false
- last:布尔值,当前循环的是否是最后一条,如果是则返回true否则返回false
案例演示
以查询emp表中信息为例演示:

a.在com.augus下创建pojo包,存放实体类
在下面创建emp实体类:
package com.augus.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.Date; @AllArgsConstructor @NoArgsConstructor @Data public class Emp implements Serializable { private Integer empno; private String ename; private String job; private Integer mgr; private Date hiredate; private Double sal; private Double comm; private Integer deptno; }
b.在com.augus下创建mapper包
在包下创建 EmpMapper接口文件
package com.augus.mapper; import com.augus.pojo.Emp; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper public interface EmpMapper { List<Emp> queryAllEmp(); }
c.在resources目录下创建包mybatis包
在里面创建EmpMapper.xml,内容如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.augus.mapper.EmpMapper"> <!--查询所有的员工信息--> <select id="queryAllEmp" resultType="emp"> select * from emp </select> </mapper>
d.在com.augus下创建service包
在包下EmpService接口:
package com.augus.service; import com.augus.pojo.Emp; import com.github.pagehelper.PageInfo; import java.util.List; public interface EmpService { List<Emp> findAll(); }
在service下创建impl包存放实现类,创建EmpServiceImpl,内容如下:
package com.augus.service.impl; import com.augus.mapper.EmpMapper; import com.augus.pojo.Emp; import com.augus.service.EmpService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class EmpServiceImpl implements EmpService { @Autowired private EmpMapper empMapper; @Override public List<Emp> findAll() { return empMapper.queryAllEmp(); } }
e.在controller包下创建 EmpController
package com.augus.controller; import com.augus.pojo.Emp; import com.augus.service.EmpService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import java.util.HashMap; import java.util.List; import java.util.Map; @Controller @RequestMapping("/emp") public class EmpController { @Autowired private EmpService empService; @RequestMapping("/findAllList") public String findAll(Map<String, Object> map){ List<Emp> all = empService.findAll(); //将员工信息添加到到视图,传递到前端页面 map.put("empList", all); //只给前端传递一个员工过去 map.put("empObj", all.get(0)); return "showEmp"; } }
f.在resources下templates下创建 showEmp.html 模板文件内容如下:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> #empTable{ width: 80%; border: 1px slategray slategray; margin: 0px auto; } #empTable th,td{ border: 1px solid slategray; text-align: center; } </style> </head> <body> <h1 style="text-align: center">展示单个员工信息</h1> <table id="empTable" cellpadding="0px" cellspacing="0px"> <tr> <th>工号</th> <th>姓名</th> <th>岗位</th> <th>上级主管</th> <th>入职日期</th> <th>薪资</th> <th>补助</th> <th>部门号</th> </tr> <!-- 判断empObj不等于null了在输出内容 --> <span th:if="${empObj} != null"> <td th:text="${empObj.empno}"></td> <td th:text="${empObj.ename}"></td> <td th:text="${empObj.job}"></td> <td th:text="${empObj.mgr}"></td> <td th:text="${empObj.hiredate}"></td> <td th:text="${empObj.sal}"></td> <td th:text="${empObj.comm}"></td> <td th:text="${empObj.deptno}"></td> </span> </table> <h1 style="text-align: center">展示所有的员工信息</h1> <table id="empTable" cellpadding="0px" cellspacing="0px"> <tr> <th>当前迭代索引</th> <th>当前迭代对象的记数</th> <th>被迭代对象的长度</th> <th>循环是否为偶数</th> <th>循环是否为奇数</th> <th>当前循环是否为第一条</th> <th>当前循环是否为最后一条</th> <th>工号</th> <th>姓名</th> <th>岗位</th> <th>上级主管</th> <th>入职日期</th> <th>薪资</th> <th>补助</th> <th>部门号</th> </tr> <!-- 判断emplist的长度是否有值,如果有值了,在往出循环取值显示 --> <span th:if="${empList.size()} ne 0"> <tr th:each="emp,i:${empList}"> <td th:text="${i.index}"></td> <td th:text="${i.count}"></td> <td th:text="${i.size}"></td> <td th:text="${i.odd}"></td> <td th:text="${i.even}"></td> <td th:text="${i.first}"></td> <td th:text="${i.last}"></td> <td th:text="${emp.empno}"></td> <td th:text="${emp.ename}"></td> <td th:text="${emp.job}"></td> <td th:text="${emp.mgr}"></td> <td th:text="${emp.hiredate}"></td> <td th:text="${emp.sal}"></td> <td th:text="${emp.comm}"></td> <td th:text="${emp.deptno}"></td> </tr> </span> </table> </body> </html>
j.测试
启动项目,在浏览器下访问 http://localhost:8080/springboot08/emp/findAllList,显示内容如下表示成功:

3.5. 对于运算符的支持
3.5.1.算数运算符:
算术运算:+ , - , * , / , %
实例演示:
<span th:text="2+1"></span> 结果:3 <span th:text="'2'+1"></span> 结果:21 <span th:text="${emp.empno}+1"></span> <span th:text="${emp.empno+1}"></span>
3.5.2.关系运算符:
- gt: great than(大于)>
- ge: great equal(大于等于)>=
- eq: equal(等于)==
- lt: less than(小于)<
- le: less equal(小于等于)<=
- ne: not equal(不等于)!=
3.5.3.逻辑运算符
- && 或 and: 表示并且
- || 或 or : 表示或者
<div th:text="1>0 and 2<3"></div> <div th:text="1>0 and 2>3"></div> <div th:text="1>0 or 2<3"></div> <div th:text="1>0 or 2>3"></div> <div th:text="${emp.sal ge 100}"></div> <div th:text="${emp.sal} ge 1800"></div> <div th:text="${emp.sal ge 800} and ${emp.deptno eq 20}"></div> <div th:text="(${emp.sal }ge 1800) or (${emp.deptno } ne 20)"></div> <div th:text="${emp.sal ge 1800 or emp.deptno ne 20 }"></div>
在早期版本的thymeleaf模板引擎框架中 逻辑运算符要写在${}的外边,目前我们2.7.5版本中,可以写在${}里面
3.5.4.三目运算符
<!-- 判断本次循环如果是偶数,则设置class属性的值为a,否则为b -->
<tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b">
3.6. th:href
设置标签的href属性值。取值使用@{}取值
案例:
根据员工编号和员工姓名删除用户信息
a.在mapper包下的的EmpMapper中添加内容后如下所示:
package com.augus.mapper; import com.augus.pojo.Emp; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper public interface EmpMapper { List<Emp> queryAllEmp(); Integer deleteEmpByEmpnoAndEname(Integer empno, String ename); }
b.在resources下的mybatis包下载EmpMapper.xml中添加根据员工编号和姓名删除员工信息SQL
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.augus.mapper.EmpMapper"> <!--查询所有的员工信息--> <select id="queryAllEmp" resultType="emp"> select * from emp </select> <!--根据员工编号的名字删除员工--> <delete id="deleteEmpByEmpnoAndEname"> DELETE from emp where empno=#{param1} AND ename=#{param2}; </delete> </mapper>
c.在com.augus下的service包进行设置
给EmpService中添加删除接口
package com.augus.service; import com.augus.pojo.Emp; import java.util.List; public interface EmpService { List<Emp> findAll(); /** * 根据编号和姓名删除员工信息 * @param empno 编号 * @param ename 姓名 * @return 删除的条数 */ Integer deleteEmpByEmpnoAndEname(Integer empno, String ename); }
d.在controller,EmpController中添加内容
package com.augus.controller; import com.augus.pojo.Emp; import com.augus.service.EmpService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import java.util.HashMap; import java.util.List; import java.util.Map; @Controller @RequestMapping("/emp") public class EmpController { @Autowired private EmpService empService; @RequestMapping("/findAllList") public String findAll(Map<String, Object> map){ List<Emp> all = empService.findAll(); //将员工信息添加到到视图,传递到前端页面 map.put("empList", all); //只给前端传递一个员工过去 map.put("empObj", all.get(0)); return "showEmp"; } //这个是给测试 a:herf准备的 @RequestMapping("/findEmp") public String findEmp(Map<String, Object> map){ List<Emp> all = empService.findAll(); //将员工信息添加到到视图,传递到前端页面 map.put("empList", all); return "findEmp"; } @RequestMapping("/deleteEmp") public String deleteEmp(Integer empno, String ename){ //根据编号和姓名删除员工信息 empService.deleteEmpByEmpnoAndEname(empno, ename); return "redirect:/emp/findEmp"; } }
e.在templates下添加 findEmp.html文件内容如下:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> #empTable{ width: 80%; border: 1px slategray slategray; margin: 0px auto; } #empTable th,td{ border: 1px solid slategray; text-align: center; } .a{ background-color: red; } .b{ background-color: yellow; } </style> </head> <body> <h1 style="text-align: center">展示所有的员工信息</h1> <!--这个只是点击删除,不会有确认事件--> <table id="empTable" cellpadding="0px" cellspacing="0px"> <tr> <th>工号</th> <th>姓名</th> <th>岗位</th> <th>上级主管</th> <th>入职日期</th> <th>薪资</th> <th>补助</th> <th>部门号</th> <th>操作</th> </tr> <!--判断emplist的长度是否有值,如果有值了,在往出循环取值显示--> <span th:if="${empList.size()} ne 0"> <!--判断这次循环是否是偶数,如果为偶数,则设置class属性的值为a,否则为b h:class="${i.odd}?a:b"--> <tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b"> <td th:text="${emp.empno}"></td> <td th:text="${emp.ename}"></td> <td th:text="${emp.job}"></td> <!--这里判断如果mgr为null, 这个字段就显示为boss,否则就显示原来内容--> <td th:text="${emp.mgr} eq null ?boss:${emp.mgr}"></td> <td th:text="${emp.hiredate}"></td> <td th:text="${emp.sal}"></td> <!--薪资这里判断一下 如果为null,则显示为0,不为null则显示原来的内容--> <td th:text="${emp.comm} eq null ?0:${emp.comm}"></td> <td th:text="${emp.deptno}"></td> <td> <a th:href="@{/emp/deleteEmp(empno=${emp.empno},ename=${emp.ename})}">删除</a> </td> </tr> </span> </table> </body> </html>
注意:这里点击会直接删除,没有任何的提示,有可能会出现误操作
f.测试
重启项目,访问:http://localhost:8080/springboot08/emp/findEmp,如下图所示单击删除按钮即可删除员工信息:

3.7. th:onclick
给元素绑定事件,单击事件并传递参数,具体用法如下:
<!--一个参数--> <button th:onclick="getNick([[${user.nick}]])">按钮1</button> <!--多参--> <button th:onclick="getNickAndPhone([[${user.nick}]], [[${user.phone}]])">按钮2</button> <!--多参, 且包含三元运算符--> <button th:onclick="getNickAndSex([[${user.nick}]], [[${user.sex==1?'男':'女'}]])">按钮3</button
案例演示在3.5中点击删除,会自动的删除掉,不会有任何提示,那么我们这里解决这个问题,点击后让出现弹窗,提示选择是否确认删除,这里还是3.5案例的环境,只是将 findEmp.html 文件内容修改如下即可实现:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> #empTable{ width: 80%; border: 1px slategray slategray; margin: 0px auto; } #empTable th,td{ border: 1px solid slategray; text-align: center; } .a{ background-color: red; } .b{ background-color: yellow; } </style> </head> <body> <h1 style="text-align: center">展示所有的员工信息</h1> <table id="empTable" cellpadding="0px" cellspacing="0px"> <tr> <th>工号</th> <th>姓名</th> <th>岗位</th> <th>上级主管</th> <th>入职日期</th> <th>薪资</th> <th>补助</th> <th>部门号</th> <th>操作</th> </tr> <!--<!– 判断emplist的长度是否有值,如果有值了,在往出循环取值显示 –>--> <span th:if="${empList.size()} ne 0"> <!-- 判断这次循环是否是偶数,如果为偶数,则设置class属性的值为a,否则为b h:class="${i.odd}?a:b" --> <tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b"> <td th:text="${emp.empno}"></td> <td th:text="${emp.ename}"></td> <td th:text="${emp.job}"></td> <!--这里判断如果mgr为null, 这个字段就显示为boss,否则就显示原来内容--> <td th:text="${emp.mgr} eq null ?boss:${emp.mgr}"></td> <td th:text="${emp.hiredate}"></td> <td th:text="${emp.sal}"></td> <!--薪资这里判断一下 如果为null,则显示为0,不为null则显示原来的内容--> <td th:text="${emp.comm} eq null ?0:${emp.comm}"></td> <td th:text="${emp.deptno}"></td> <td> <!-- 这个位置采用 deleteEmpByEmpnoANDEname([[${emp.empno}]],[[${emp.ename}]] 这里idea会存在误报错 --> <a href="javascript:void(0)" th:onclick="deleteEmpByEmpnoANDEname([[${emp.empno}]],[[${emp.ename}]])">删除</a> </td> </tr> </span> </table> <script> function deleteEmpByEmpnoANDEname(empno, ename) { var result = confirm("确定要删除的编号为:"+empno+",姓名为:"+ename) if(result){ /* * 这个地方只需要具体的方法url地址就行,上下文路径做的响应重定向,会自动添加*/ window.location.href="deleteEmp?empno="+empno+"&ename="+ename; } } </script> </body> </html>
测试,重启项目浏览器访问:http://localhost:8080/springboot08/emp/findEmp,如下,在删除的时候会有弹窗出现询问是否会删除,点击确定即可删除,点击取消则不会删除

四、内置对象
Thymeleaf提供了一些内置对象,内置对象可直接在模板中使用。这些对象是以#引用的。
使用内置对象的语法
- 引用内置对象需要使用#
- 大部分内置对象的名称都以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和域对象
4.1.strings对象

4.2.dates

4.3.numbers
#numbers.formatDecimal(numbwe,整数位,整数位千分位标识符,小数位,小数位表示符)
${#numbers.formatDecimal(num,1,'COMMA',2,'POINT')}
案例:
表示整数位至少一位,不足以0补齐,如:num = 123,
${#numbers.formatDecimal(num,1,'COMMA',2,'POINT')} 则显示 123.00
${#numbers.formatDecimal(num,10,'COMMA',2,'POINT')} 则显示 0,000,000,123.00
COMMA表示:','
POINT表示:‘.’
4.4.域对象

使用本章节环境搭建时候的测试文件,在controller中ShowController文件中添加内容如下:
package com.augus.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.Map; @Controller public class ShowController { @RequestMapping("/show") public String freeMarkerShow(Map<String, Object> map, HttpServletRequest httpServletRequest, HttpSession session){ //给request域中放入数据 httpServletRequest.setAttribute("msg","helloHttpServletRequest"); //给session域中放入数据 session.setAttribute("msg", "helloHttpSession"); //向appilcation域中放入数据 httpServletRequest.getServletContext().setAttribute("msg","helloAppilcation"); //向前端传递数据 map.put("name", "梦特娇"); //返回模块文件名称 return "show"; } }
在templates中修改show.html内容如下:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> this is show.html <div th:text="${name}"></div> <br> <h1>从HttpServletRequest中取出数据</h1><br> <span th:text="${#httpServletRequest.getAttribute('msg')}"></span><br> <span th:text="${#request.getAttribute('msg')}"></span><br> <span th:text="${msg}"></span><br> <h1>从httpSession中取出数据</h1><br> <span th:text="${#httpSession.getAttribute('msg')}"></span><br> <span th:text="${#session.getAttribute('msg')}"></span><br> <span th:text="${session.msg}"></span><br> <h1>从httpSession中取出数据的方式:</h1><br> <span th:text="${#servletContext.getAttribute('msg')}"></span><br> <span th:text="${application.msg}"></span> </body> </html>
重启项目,然后再浏览器访问 http://localhost:8080/springboot08/show,如下图可以从域中取出数据:


浙公网安备 33010602011771号