无法通过Thymeleaf与Spring编辑数据库数据的问题求助
图书编辑表单提交404及数据未保存问题修复
点击编辑按钮可正常跳转并填充数据,但提交后出现404错误、数据未保存,问题出在以下几个环节,对应修复方案如下:
1. 表单提交路径缺失ID参数
bookUpdate.html中表单的th:action仅设置为@{/bookUpdate},但后端@PostMapping的接口路径是/bookUpdate/{id},提交时未携带目标图书ID,导致找不到匹配的POST接口,触发404。
修复代码:
修改表单的action,携带当前图书ID:
<form th:action="@{/bookUpdate/{id}(id=${book.id})}" th:object="${book}" method="post">
2. 表单字段绑定方式错误
当前使用th:value="${book.topic}"填充字段,无法让Spring MVC正确将用户输入的新值绑定到BookDto对象,导致后端接收不到更新后的参数。需使用th:field配合th:object实现双向绑定。
修复代码:
替换所有输入字段的th:value为th:field:
<div class="form-group"> <label for="topic" class="form-control-label">Topic</label> <input type="text" class="form-control" th:field="*{topic}" id="topic" /> </div> <div class="form-group"> <label for="description" class="form-control-label">Description</label> <textarea class="form-control" th:field="*{description}" id="description" style="height: 95px"></textarea> </div> <div class="form-group"> <label for="link" class="form-control-label">Link</label> <input type="text" class="form-control" th:field="*{link}" id="link" /> </div>
3. 控制器参数绑定与校验问题
@GetMapping传入模型的是Book实体,但editBook方法接收的是BookDto,类型不匹配会导致参数绑定失败;- 使用
@Valid校验但未添加BindingResult参数,校验失败时会直接抛出异常,无法友好返回编辑页面。
修复代码:
调整控制器方法,确保参数类型匹配,并添加校验结果处理:
@PostMapping("/bookUpdate/{id}") public String editBook(@Valid BookDto book, BindingResult result, @PathVariable(value = "id") Integer id, Model model) { if (result.hasErrors()) { // 校验失败,返回编辑页面并回显原有数据 model.addAttribute("book", service.findById(id)); return "views/bookUpdate"; } Book oldBook = service.findById(id); oldBook.setDescription(book.getDescription()); oldBook.setTopic(book.getTopic()); oldBook.setLink(book.getLink()); service.saveBook(oldBook); return "redirect:/bookList"; }
若
service.findById返回的是Book实体而非BookDto,建议在@GetMapping方法中将实体转换为BookDto后传入模型,或者直接将editBook方法的参数改为Book实体(根据业务逻辑调整)。
可选优化:用隐藏字段传递ID
如果担心路径参数传递问题,可在表单内添加隐藏字段传递ID,同时调整后端接口路径:
<!-- 在表单内添加隐藏字段 --> <input type="hidden" th:field="*{id}" />
后端对应调整:
@PostMapping("/bookUpdate") public String editBook(@Valid BookDto book, BindingResult result, Model model) { if (result.hasErrors()) { model.addAttribute("book", service.findById(book.getId())); return "views/bookUpdate"; } Book oldBook = service.findById(book.getId()); oldBook.setDescription(book.getDescription()); oldBook.setTopic(book.getTopic()); oldBook.setLink(book.getLink()); service.saveBook(oldBook); return "redirect:/bookList"; }
内容的提问来源于stack exchange,提问作者Anastasia
相关产品推荐
相关产品推荐

