英文:
the expression inside th:field gives Neither BindingResult nor plain target object for bean name error
问题
I am trying to create a table that can be saved as a form, but I am encountering an error: "Neither BindingResult nor plain target object for bean name 'rows[0]' available as request attribute." The issue seems to be related to the usage of "rows" inside th:field, but I can't figure out how to fix it.
以下是代码示例:
// 实体类
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;
}
// 控制器类
@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", "", ""));
    
    model.addAttribute("rows", rows);
    
    return "timetable/timetable_new";
}
// 表单部分
<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
英文:
I am trying to create table that can be saved as a form and I am Neither BindingResult nor plain target object for bean name 'rows[0]' available as request attribute. I can see the problem is from rows used inside th:field but can figure out how to fix it
Below is the code sample
//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;
}
//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("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";
	}
<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>
picture of what I am trying to achieve
generated error
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
答案1
得分: 0
If you're using th:field, then you need to add a model attribute to your model and set it as the th:object of your <form />. Since you are using a variable named rows, your th:object should look like this:
如果你正在使用th:field,那么你需要在你的模型中添加一个模型属性,并将其设置为你的<form />的th:object。由于你正在使用名为rows的变量,你的th:object应该如下所示:
public class TimeTableForm {
    private List<TimeTable> rows;
    public void setRows(List<TimeTable> rows) {
        this.rows = rows;
    }
    public List<TimeTable> getRows() {
        return rows;
    }
}
it must be added to your model in your controller:
它必须在你的控制器中添加到你的模型中:
TimeTableForm form = new TimeTableForm();
form.setRows(rows);
model.addAttribute("timeTableForm", timeTableForm);
and your form must be updated to reflect the new object:
并且你的表单必须更新以反映新的对象:
<form th:action="@{/timetable/save}" th:object="timeTableForm" method="post">
(Note: The code snippets provided are in both Chinese and English as requested.)
英文:
If you're using th:field, then you need to add a model attribute to your model and set it as the th:object of your <form />.  Since you are using a variable named rows, your th:object should look like this:
public class TimeTableForm {
    private List<TimeTable> rows;
    public void setRows(List<TimeTable> rows) {
        this.rows = rows;
    }
    public List<TimeTable> getRows() {
        return rows;
    }
}
it must be added to your model in your controller:
TimeTableForm form = new TimeTableForm();
form.setRows(rows);
model.addAttribute("timeTableForm", timeTableForm);
and your form must be updated to reflect the new object:
<form th:action="@{/timetable/save}" th:object="timeTableForm" method="post">
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。



评论