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

Thymeleaf表单提交Todo对象字段为空的问题求助

问题排查与解决方案

问题根源

核心问题是Java Record的无参构造器干扰了Spring MVC的数据绑定机制:

  1. 你为Todo Record手动添加了无参构造器,Spring MVC处理表单提交时会优先调用该构造器创建实例。
  2. Java Record默认没有Setter方法,Spring无法通过常规JavaBean属性填充方式为字段赋值,最终所有字段保持无参构造器中的默认值。
  3. 若你的Spring版本低于6.x(对应Spring Boot 3.x),旧版本对Java Record的构造器绑定支持有限,会加剧这个问题。

解决方案

方案一:改用普通JavaBean(推荐新手使用)

将Todo Record改为标准Java实体类,提供Getter、Setter和无参构造器,这是Spring MVC兼容性最好的方式:

import jakarta.persistence.Id;

public class Todo {
    @Id
    private Long id;
    private Long userId;
    private String name;
    private String description;
    private boolean completed;

    // 无参构造器
    public Todo() {
        this(null, null, "", "", false);
    }

    // 全参构造器
    public Todo(Long id, Long userId, String name, String description, boolean completed) {
        this.id = id;
        this.userId = userId;
        this.name = name;
        this.description = description;
        this.completed = completed;
    }

    // Getter和Setter方法
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public Long getUserId() { return userId; }
    public void setUserId(Long userId) { this.userId = userId; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }
    public boolean isCompleted() { return completed; }
    public void setCompleted(boolean completed) { this.completed = completed; }

    @Override
    public String toString() {
        return "Todo[id=" + id + ", userId=" + userId + ", name=" + name + ", description=" + description + ", completed=" + completed + "]";
    }
}

方案二:保留Java Record(需Spring 6+)

若坚持使用Java Record,需做以下调整:

  1. 移除手动添加的无参构造器,让Spring通过Record默认生成的全参构造器进行参数绑定:
import jakarta.persistence.Id;

// 移除自定义无参构造器,使用Record默认的全参构造器
public record Todo(@Id Long id, Long userId, String name, String description, boolean completed) {}
  1. 修改Controller中的实例化代码,因无无参构造器,需用全参构造器创建Todo实例:
@GetMapping
public String getAllTodos(Model model) {
    List<Todo> todos = todoRepository.findAll();

    model.addAttribute("todos", todos);
    // 使用全参构造器创建空实例
    model.addAttribute("todo", new Todo(null, null, "", "", false));
    return "test";
}
  1. 确保Spring版本为6.x及以上(即Spring Boot 3.x及以上),旧版本Spring不支持通过构造器自动绑定Record参数。

额外检查点

  • 你的Thymeleaf表单配置正确:th:object="${todo}"和th:field="*{name}"会自动生成正确的表单参数名称,无需调整。
  • Spring Boot默认开启CSRF防护,Thymeleaf的<form>标签会自动注入CSRF令牌,不会导致参数丢失。

内容的提问来源于stack exchange,提问作者Ike Osenberg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:19:57