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

无法通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 23:54:23