Spring MVC Thymeleaf 单表单批量更新Todo对象问题求助
解决方案
1. 创建表单包装类
首先定义一个用于封装Todo列表的表单包装类,Spring MVC无法直接绑定顶级集合,需要通过包装类中转:
public class TodoListForm { private List<Todo> todos; // 空构造器(Spring MVC绑定必需) public TodoListForm() {} public TodoListForm(List<Todo> todos) { this.todos = todos; } // Getter和Setter方法 public List<Todo> getTodos() { return todos; } public void setTodos(List<Todo> todos) { this.todos = todos; } }
2. 修改Controller代码
调整表单展示方法
将查询到的Todo列表包装进表单对象,再添加到Model中:
@PostMapping("/todos/update-multiple-form") public String updateMultipleForm(@RequestParam List<Integer> ids, Model model){ List<Todo> todos = new ArrayList<>(); ids.forEach(id -> todos.add(service.get(id))); // 把列表包装到表单对象后传入模板 model.addAttribute("todoListForm", new TodoListForm(todos)); return "update-multiple"; }
调整批量更新方法
通过@ModelAttribute接收表单包装类,而非直接接收List<Todo>:
@PostMapping("/todos/update-multiple") public String updateMultiple(@ModelAttribute TodoListForm todoListForm, Model model){ todoListForm.getTodos().forEach(service::update); return "redirect:/todos"; }
3. 修改Thymeleaf模板
- 添加
th:object绑定表单包装类 - 修正表达式路径,移除冗余的
th:checked(th:field会自动处理复选框状态) - 修复提交按钮的拼写错误(
upate→update)
<form th:object="${todoListForm}"> <div th:each="todo, iter : *{todos}"> <input type="hidden" th:field="*{todos[__${iter.index}__].id}" /> <input type="text" class="form-control" th:field="*{todos[__${iter.index}__].desc}"/> <input type="checkbox" th:field="*{todos[__${iter.index}__].done}"/> </div> <input type="submit" name="update" value="update" formmethod="post" formaction="/todos/update-multiple" class="btn btn-danger"/> <input type="submit" name="cancel" value="cancel" formmethod="get" formaction="/todos" class="btn btn-secondary"/> </form>
核心说明
- 表单包装类解决了Spring MVC无法直接绑定顶级集合的问题,提交的参数会以
todos[0].id、todos[0].desc格式被正确映射到集合元素。 th:object="${todoListForm}"指定了Thymeleaf的绑定根对象,让*{}表达式能正确解析集合路径,消除了找不到todos[0]绑定对象的错误。- 复选框的选中状态由
th:field自动处理,无需额外添加th:checked,避免状态不一致问题。
内容的提问来源于stack exchange,提问作者Cheng Thao
相关产品推荐
相关产品推荐

