Spring Boot整合Thymeleaf删除数据库记录跳转404错误排查
问题描述
在HTML页面触发order类型的数据库条目删除操作时,未跳转至预期目标页面,直接返回404错误页。点击删除按钮后请求地址为http://localhost:8080/deleteOrder/1,返回错误信息如下:
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Jun 21 22:49:08 EEST 2022
There was an unexpected error (type=Not Found, status=404).
No message available
关联代码
Controller层代码
@RequestMapping(value = "supplier/orders/review") public String reviewOrders(Model model){ model.addAttribute("orders", ordersRepository.findAll()); return "ReviewOrders"; } @RequestMapping(value = "/deleteOrder/{id}", method = RequestMethod.GET) public String deleteOrder(@PathVariable("id") Integer id){ Orders orders = ordersRepository.getById(id); ordersRepository.delete(orders); return "redirect:/SupplierDashboard"; }
前端Thymeleaf页面代码
</tr> <tr th:each="orders:${orders}" class="table-row"> <td th:text="${orders.id}">Id</td> <td th:text="${orders.product_name}">Name</td> <td th:text="${orders.product.price}">Price</td> <td th:text="${orders.product.description}">desc</td> <td th:text="${orders.product.category}">category</td> <td th:text="${orders.product.quantity}">quantity</td> <td th:text="${orders.product.supplier.firstName}">supplier name</td> <td> <a th:href="@{/deleteOrder/{id} (id = ${orders.id})}" class="btn btn-danger ml-2">Delete</a> </td>
排查方向与修复方案
404的核心原因是请求路径没有匹配到对应的处理器方法,按优先级排查以下点:
- 检查Controller类级别的
@RequestMapping前缀配置
你当前reviewOrders方法的映射路径没有写开头斜杠,如果Controller类上配置了类级别的路径前缀(比如@RequestMapping("/supplier")),那么deleteOrder方法的实际映射路径会变成/supplier/deleteOrder/{id},但前端写的请求路径是根路径下的/deleteOrder/{id},自然匹配不到。
启动项目时控制台会打印所有注册的请求映射,直接搜索deleteOrder就能看到方法对应的实际访问路径,把前端Thymeleaf的链接路径和实际映射对齐即可。 - 检查重定向目标路径是否存在
即使deleteOrder方法匹配成功,方法执行完会重定向到/SupplierDashboard,如果项目中没有编写对应路径的控制器方法,且路径大小写完全不匹配(Spring MVC默认路径匹配大小写敏感),也会报404。需要确认存在处理/SupplierDashboard请求的方法,且对应视图文件存在。 - 检查权限框架、拦截器/过滤器配置
如果项目中集成了Spring Security、Shiro等权限框架,或者配置了自定义拦截器,确认是否对/deleteOrder/**路径做了拦截,拦截后转发到不存在的路径也会返回404。
另外有两个编码优化点:
- 删除操作不要使用GET请求,GET请求会被浏览器缓存、可能被搜索引擎爬虫误触发,存在数据误删风险,建议改成POST或DELETE请求提交。
ordersRepository.getById(id)是JPA提供的延迟加载方法,传入不存在的id时会直接抛出代理加载异常,建议改成ordersRepository.findById(id).orElseThrow(() -> new RuntimeException("订单不存在")),先校验订单存在再执行删除逻辑。
内容的提问来源于stack exchange,提问作者andreeap
相关产品推荐
相关产品推荐

