You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 05:40:22