本文最后更新于11 天前,其中的信息可能已经过时,如有错误请发送邮件到kirasu@qq.com
Thymeleaf 开发常见坑点
SpringBoot + Thymeleaf 开发中高频踩坑问题汇总
一、缓存相关(最常遇到)
- 现象:修改html页面,刷新浏览器看不到变化,必须重启项目
原因:Thymeleaf默认开启模板缓存
解决:开发环境在application.yml关闭缓存spring: thymeleaf: cache: false
⚠️注意:生产环境务必开启 cache: true,提升性能
- IDEA额外坑: IDEA默认不会自动编译资源文件。修改html后,需要手动Build项目(Ctrl+F9)才能加载最新页面。
二、文件路径问题
- templates目录下html不能直接访问 templates是服务端渲染目录,浏览器不能直接输入
/index.html访问,必须Controller返回视图名称。 静态资源css、js、图片放在resources/static/,才可以直接访问。 -
th:href / th:href 路径写法错误 ❌ 错误:
<a href="/user/1">硬编码,不推荐 ✅ 正确:<a th:href="@{/user/1}">@{}会自动拼接项目上下文路径,部署项目不容易404
三、转义 th:text 和 th:utext 的安全坑
- th:text:自动转义html标签,防止XSS攻击,优先使用
-
th:utext:原样解析HTML,如果渲染用户输入内容,极易XSS漏洞
禁止直接将用户提交的数据使用 th:utext 展示!
四、表达式语法坑
- 表达式必须写
${},漏写$会不生效 ❌<p th:text="username"></p>✅<p th:text="${username}"></p> - 比较符号:
>``<在html中会解析成标签,两种方案
<!--方案1:使用内置别名 -->
th:if="${age ge 18}" >=
th:if="${age lt 18}" <
th:if="${age le 18}" <=
th:if="${age gt 18}" >
<!--方案2:转义写法 > < -->
th:if="${age > 18}"
五、th:each循环坑
- 状态变量stat必须定义,否则不能使用stat.count / stat.index ❌
<li th:each="fruit:${list}">没有stat变量 ✅<li th:each="fruit,stat : ${list}"> - 空集合不会报错,页面不会渲染任何标签;如果想展示空提示,需要搭配
#lists.isEmpty()
<p th:if="${#lists.isEmpty(fruitList)}">暂无数据</p>
六、实体对象取值空指针
当model中对象为null,直接访问属性会抛异常
<!--如果user为null,${user.name}直接报错-->
<p th:text="${user.name}"></p>
<!--安全写法,使用?空安全运算符-->
<p th:text="${user?.name}"></p>
七、命名空间忘记引入
页面html头部必须添加命名空间,否则IDEA没有语法提示,部分属性失效
<html xmlns:th="[http://www.thymeleaf.org](http://www.thymeleaf.org)">
八、三元运算符坑
三元表达式,字符串常量必须加引号 ❌ <div th:class="${vip} ? vip : normal"></div> ✅ <div th:class="${vip} ? 'vip' : 'normal'"></div>
九、内置工具对象使用注意
内置对象以#开头:#strings、#lists、#dates
内置对象只能在Thymeleaf表达式
${}里面使用,不能写在普通文本
十、其他小问题
- 中文乱码:配置
spring.thymeleaf.encoding=UTF-8 - 静态预览:直接双击html打开看到的是默认文本,只有后端渲染才会替换${}变量,这是thymeleaf正常特性,不是bug