Thymeleaf执行#session.removeAttribute表达式报错,求解决办法
解决Thymeleaf中移除会话属性报错的问题
问题重现
你尝试在Thymeleaf模板中通过以下代码移除Session属性:
<div th:if="${session.message}" th:classappend="${session.message.type}" class="alert" role="alert"> <p class="text-center" th:text="${session.message.content}"></p> <th:block th:text="${#session.removeAttribute('message')}"></th:block> </div>
执行时抛出如下错误:
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "#session.removeAttribute('message')" (template: "signup" - line 19, col 43) at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393) at org.attoparser.MarkupParser.parse(MarkupParser.java:257) at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230) ... 48 more
Controller中设置Session属性的代码如下:
User addedUser = this.userRepository.save(user); model.addAttribute("user", new User()); session.setAttribute("message", new Message("Successfully Register", "alert-success")); return "signup"; } catch (Exception e) { e.printStackTrace(); model.addAttribute("user", user); session.setAttribute("message", new Message("Server Error !!" + e.getMessage(), "alert-danger")); return "signup"; }
错误原因
th:text="${#session.removeAttribute('message')}"报错的核心原因是:HttpSession.removeAttribute()方法返回值为void,而th:text要求绑定的Spring EL表达式必须返回一个可转换为字符串的结果,Spring EL无法处理返回void的方法调用,因此抛出解析异常。
解决方案
方案一:使用Spring MVC Flash属性(推荐)
Flash属性是Spring MVC专门为一次性消息场景设计的机制,它会在重定向后的下一次请求中自动清除,无需手动操作Session,是更优雅的实现方式。
修改Controller代码
将原来的session.setAttribute()替换为RedirectAttributes.addFlashAttribute(),并改为重定向到signup页面:
// 成功分支 User addedUser = this.userRepository.save(user); redirectAttributes.addFlashAttribute("message", new Message("Successfully Register", "alert-success")); return "redirect:/signup"; // 重定向到signup页面 // 错误分支 catch (Exception e) { e.printStackTrace(); redirectAttributes.addFlashAttribute("message", new Message("Server Error !!" + e.getMessage(), "alert-danger")); return "redirect:/signup"; }
修改Thymeleaf模板
直接访问Flash属性即可,无需手动移除:
<div th:if="${message}" th:classappend="${message.type}" class="alert" role="alert"> <p class="text-center" th:text="${message.content}"></p> </div>
方案二:在Thymeleaf中正确执行Session属性移除
如果必须继续使用Session存储消息,可通过th:with标签执行removeAttribute()方法——th:with允许执行无返回值的表达式,不会要求结果可渲染:
<div th:if="${session.message}" th:classappend="${session.message.type}" class="alert" role="alert"> <p class="text-center" th:text="${session.message.content}"></p> <!-- 用th:with执行移除操作,定义一个无用变量触发方法执行 --> <th:block th:with="dummy=${#session.removeAttribute('message')}"></th:block> </div>
内容的提问来源于stack exchange,提问作者Umar Aftab
相关产品推荐
相关产品推荐

