Thymeleaf拼接+号报错与@ControllerAdvice注入ctotal变量红线问题
Thymeleaf开发两类报错解决方案
问题1:th:href字符串拼接抛出unexpected '+'错误
错误原因
Thymeleaf的@{}是链接处理专属表达式,所有拼接内容必须放在表达式括号内部,你将查询参数拼接逻辑写在了@{}外部,不符合语法规范。
错误代码
<a th:href="@{'/cart/add/'+${el.value.id}} + '?cartPage=true'" class="btn btn-success btn-sm">+</a>
修复方案
推荐使用Thymeleaf原生参数传递写法,更规范且自动处理转义:
<a th:href="@{/cart/add/{id}(id=${el.value.id}, cartPage=true)}" class="btn btn-success btn-sm">+</a>
也可以将完整拼接逻辑移入@{}内部:
<a th:href="@{'/cart/add/' + ${el.value.id} + '?cartPage=true'}" class="btn btn-success btn-sm">+</a>
问题2:模板中引用@ControllerAdvice注入的ctotal变量报红线
错误原因
- 运行时报错:你仅在session存在购物车对象时才往Model中添加
ctotal变量,用户首次访问、购物车为空场景下,Model中无该属性,模板引用直接报错 - IDE仅红线提示不影响运行:IDEA静态检查无法识别
@ControllerAdvice注入的全局模型属性,属于误报
修复方案
第一步:修改common.kt逻辑,给变量设置默认值,无论购物车是否存在都注入模型
把csize、ctotal的赋值逻辑移出购物车非空判断:
@ModelAttribute fun sharedData(model: Model, session: HttpSession, principal: Principal?) { if (principal != null) { model.addAttribute("principal", principal.name) } val pages: List<Page> = pageRepo.findAllByOrderBySortingAsc() val categories: List<Category> = categoryRepo.findAllByOrderBySortingAsc() var cartActive = false // 提前初始化默认值 var size = 0 var total = 0.0 if (session.getAttribute("cart") != null) { val cart: HashMap<Int, Cart> = session.getAttribute("cart") as HashMap<Int, Cart> for (value in cart.values) { size += value.quantity total += value.quantity * value.price.toDouble() } cartActive = true } // 统一添加到模型,不受购物车是否存在影响 model.addAttribute("csize", size) model.addAttribute("ctotal", total) model.addAttribute("cpages", pages) model.addAttribute("ccategories", categories) model.addAttribute("cartActive", cartActive) }
第二步(可选):模板中添加变量默认值兜底,彻底避免空值报错
用?:运算符给ctotal设置兜底默认值:
<td colspan="1" th:text="'$' + ${#numbers.formatDecimal(ctotal ?: 0.0, 0, 'COMMA', 2, 'POINT')}"></td>
内容的提问来源于stack exchange,提问作者Mama
相关产品推荐
相关产品推荐

