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

使用th:field绑定列表数据时出现Neither BindingResult错误求助

问题:表单提交时抛出Neither BindingResult nor plain target object for bean name 'rows[0]'错误

尝试创建可提交保存的表格表单,运行时抛出错误:

Neither BindingResult nor plain target object for bean name 'rows[0]' available as request attribute

已定位问题出在th:field中使用rows的部分,但不知如何修复。

相关代码示例

实体类代码

//Entity class
public class TimeTable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Integer id;

    String day;
    
    @Column(name="start_time")
    String startTime;
    
    @Column(name = "end_time")
    String endTime;

    // 补充带参构造方法(原代码调用了该构造,需显式声明)
    public TimeTable() {}
    
    public TimeTable(String day, String startTime, String endTime) {
        this.day = day;
        this.startTime = startTime;
        this.endTime = endTime;
    }
}

控制器代码

//controller class
@GetMapping("/timetable/new")
public String newTimetable(Model model) {
    
    List<TimeTable> rows = new ArrayList<>();
    rows.add(new TimeTable("Monday", "", ""));
    rows.add(new TimeTable("Tuesday", "", ""));
    rows.add(new TimeTable("Wednesday", "", ""));
    rows.add(new TimeTable("Thursday", "", "")); // 修正原拼写错误Thusday
    rows.add(new TimeTable("Friday", "", ""));
    rows.add(new TimeTable("Saturday", "", ""));
    rows.add(new TimeTable("Sunday", "", ""));
    
    //model.addAttribute("timetableObject", new TimeTable());
    model.addAttribute("rows", rows);
    
    return "timetable/timetable_new";
}

Thymeleaf视图代码

<form th:action="@{/timetable/save}" method="post" >
    <table class="table table-striped table-hover table-responsive-sm align-middle" id="tableRefresh">
        <thead class=" text-center">
            <tr>
                <th scope="col">Day</th>
                <th scope="col">Start Time</th>
                <th scope="col">End Time</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="row, rowStat : ${rows}">
                <td>[[${row.day}]]</td>
                <td>
                    <input type="text" name="startTime"  th:field="*{rows[__${rowStat.index}__].startTime}" class="form-control">
                </td>
            </tr>
        </tbody>
    </table>
    <button type="submit" class="form-control btn btn-outline-success">Save</button>
</form>

错误栈信息

Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'rows[0]' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153)
at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:926)
at org.thymeleaf.spring6.context.webmvc.SpringWebMvcThymeleafRequestContext.getBindStatus(SpringWebMvcThymeleafRequestContext.java:232)
at org.thymeleaf.spring6.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:306)
at org.thymeleaf.spring6.util.FieldUtils.getBindStatus(FieldUtils.java:253)
at org.thymeleaf.spring6.util.FieldUtils.getBindStatus(FieldUtils.java:227)
at org.thymeleaf.spring6.processor.AbstractSpringFieldTagProcessor.doProcess(AbstractSpringFieldTagProcessor.java:174)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
... 116 more

解决方案

问题原因

Thymeleaf的th:field使用选择表达式*{}时,需要表单绑定一个根对象(通过th:object指定),选择表达式会基于这个根对象进行属性查找。原代码中没有指定th:object,直接用集合rows作为绑定目标,导致Thymeleaf错误地尝试查找名为rows[0]的请求属性,从而抛出异常。

修复步骤

1. 创建表单包装类

创建一个包含List<TimeTable>属性的包装类,作为表单绑定的根对象:

public class TimeTableForm {
    private List<TimeTable> rows;

    // Getter和Setter
    public List<TimeTable> getRows() {
        return rows;
    }

    public void setRows(List<TimeTable> rows) {
        this.rows = rows;
    }
}

2. 修改控制器代码

将集合包装到TimeTableForm中,添加到Model作为表单绑定对象:

@GetMapping("/timetable/new")
public String newTimetable(Model model) {
    List<TimeTable> rows = new ArrayList<>();
    rows.add(new TimeTable("Monday", "", ""));
    rows.add(new TimeTable("Tuesday", "", ""));
    rows.add(new TimeTable("Wednesday", "", ""));
    rows.add(new TimeTable("Thursday", "", ""));
    rows.add(new TimeTable("Friday", "", ""));
    rows.add(new TimeTable("Saturday", "", ""));
    rows.add(new TimeTable("Sunday", "", ""));
    
    TimeTableForm form = new TimeTableForm();
    form.setRows(rows);
    model.addAttribute("timeTableForm", form); // 绑定根对象
    
    return "timetable/timetable_new";
}

3. 修改Thymeleaf视图

在<form>标签中添加th:object="${timeTableForm}"指定根对象,同时修正th:field的表达式,去掉手动设置的name属性(th:field会自动生成正确的name):

<form th:action="@{/timetable/save}" method="post" th:object="${timeTableForm}">
    <table class="table table-striped table-hover table-responsive-sm align-middle" id="tableRefresh">
        <thead class=" text-center">
            <tr>
                <th scope="col">Day</th>
                <th scope="col">Start Time</th>
                <th scope="col">End Time</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="row, rowStat : ${timeTableForm.rows}">
                <td>[[${row.day}]]</td>
                <td>
                    <input type="text" th:field="*{rows[__${rowStat.index}__].startTime}" class="form-control">
                </td>
                <td>
                    <input type="text" th:field="*{rows[__${rowStat.index}__].endTime}" class="form-control">
                </td>
            </tr>
        </tbody>
    </table>
    <button type="submit" class="form-control btn btn-outline-success">Save</button>
</form>

4. 添加保存接口的控制器方法

接收TimeTableForm对象,处理表单提交的数据:

@PostMapping("/timetable/save")
public String saveTimetable(@ModelAttribute TimeTableForm form) {
    // 遍历form.getRows(),将每个TimeTable保存到数据库
    // 示例:timeTableRepository.saveAll(form.getRows());
    return "redirect:/timetable"; // 保存后重定向到列表页
}

可选临时方案(不推荐)

如果不想创建包装类,可以直接使用变量表达式${}替代选择表达式*{},手动设置name属性实现参数绑定,但这种方式无法利用Spring表单绑定的验证、错误提示等功能:

<input type="text" name="rows[__${rowStat.index}__].startTime" th:value="${row.startTime}" class="form-control">

内容的提问来源于stack exchange,提问作者Solomon Otoo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 16:07:05