Spring Boot+Thymeleaf:@ModelAttribute接收前端对象为空问题
问题场景
要在HTML编辑视图预填待更新的Invoice对象字段,通过Thymeleaf生成编辑链接传递对象,Spring MVC接口用@ModelAttribute接收,但接收的Invoice仅完成实例化,所有属性为空,打印显示为main.domain.model.Invoice@37567a3b。
根因分析
Thymeleaf的@{/edit(invoice=${invoice})}写法会将整个Invoice对象的toString()结果作为请求参数值传递(即URL会变成/edit?invoice=main.domain.model.Invoice@xxx),而非拆分对象属性为独立请求参数。Spring MVC无法将该字符串映射到Invoice的属性上,仅能通过无参构造实例化对象,导致属性全为空。
解决方案
1. 修正Thymeleaf编辑链接的参数传递方式
将Invoice的属性拆分为独立请求参数传递,Thymeleaf提供两种简洁写法:
方式一:手动指定每个属性
<a th:href="@{/edit(id=${invoice.id}, price=${invoice.price}, date=${invoice.date}, name=${invoice.name})}">编辑</a>
方式二:自动展开对象属性(推荐)
使用Thymeleaf的*语法自动将对象属性转为请求参数:
<a th:href="@{/edit(*{invoice})}">编辑</a>
该写法会自动生成类似/edit?id=1&price=100&date=2024-05-20&name=测试订单的URL。
2. 确保Spring MVC接口正确接收参数
无需额外复杂配置,直接将Invoice作为方法参数,Spring会自动通过请求参数名匹配属性完成绑定;同时确保实体类满足以下要求:
- 存在无参构造方法(Spring实例化对象必需)
- 每个属性都有对应的
getter和setter方法(Spring通过setter赋值)
示例接口代码:
@GetMapping("/edit") public String showEditForm(Invoice invoice, Model model) { // 此时invoice的属性已完成绑定 model.addAttribute("invoice", invoice); return "edit-invoice"; // 返回编辑页视图名 }
3. 验证日期格式匹配
如果Invoice的date字段添加了@DateTimeFormat注解,需确保传递的日期格式与注解指定的一致。例如:
@DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate date;
则Thymeleaf传递的date参数必须为yyyy-MM-dd格式(如2024-05-20),否则日期属性会绑定失败为null。
内容的提问来源于stack exchange,提问作者NeQ

