Thymeleaf循环遍历时OGNL表达式求值异常该如何排查?
异常产生原因
核心问题是模型key的命名不符合OGNL表达式的默认变量命名规则:
- OGNL语法中
-是算术减法运算符,模板中写的${votes-positive}不会被识别为取key为votes-positive的模型变量,而是会被解析为「计算变量votes减去变量positive的值」。由于这两个变量在模型中都不存在,表达式最终要么返回null,要么返回默认数值类型。 - 如果表达式返回null:部分版本Thymeleaf的
th:each迭代null时会生成空的迭代变量vote,后续访问vote.name触发空指针类的求值异常。 - 如果表达式返回默认数值:
th:each迭代数值时会生成对应次数的循环,此时vote变量是数字类型,本身没有name属性,直接触发属性不存在的求值异常。
修复方案
两种方案可选:
- (更推荐)后端调整模型key的命名,避免使用特殊运算符,比如把key改为
votesPositive,模板直接写${votesPositive}即可正常访问。 - 模板端使用特殊语法访问带特殊字符的key,两种写法都可生效:
- 用上下文对象获取:
th:each="vote : ${#ctx.getVariable('votes-positive')}" - 用数组访问语法:
th:each="vote : ${['votes-positive']}"
- 用上下文对象获取:
Thymeleaf 调试能力说明
调试模式
Thymeleaf本身支持开启调试模式,开启后会输出更详细的表达式求值上下文日志:
- SpringBoot环境:在application配置文件中添加配置
spring.thymeleaf.mode=DEBUG - 原生环境:初始化
TemplateEngine时调用templateEngine.setDebugEnabled(true)
模型树打印
无需额外配置,直接在模板中插入调试代码即可输出全部/指定模型变量的结构:
- 打印全部模型变量:
运行后页面会输出所有传递到模板的键值对,可直接检查对应key是否存在、值的类型和内容是否符合预期。<div th:text="${#ctx.getVariables()}"></div> - 打印单个变量的完整结构:
比如要排查<div th:text="${#objects.toString(待检查的变量表达式)}"></div>votes-positive的内容,可临时插入<div th:text="${#objects.toString(#ctx.getVariable('votes-positive'))}"></div>,即可看到该变量的完整序列化结果。
内容的提问来源于stack exchange,提问作者Luís Soares
相关产品推荐
相关产品推荐

