Spring Boot账户转账接口出现404 Not Found错误求助
账户转账接口404错误排查与修复
核心问题定位
调用路径/api/api/acco/treansfer/1/2/20000返回404,主要由路径配置重复、拼写错误、Controller类定义缺失导致,同时Repository层SQL存在语法问题,以下是具体修复方案:
1. 修复Controller路径与类定义问题
问题点:
- 上下文路径重复:
application.properties已设置server.servlet.context-path=/api,但Controller类上的@RequestMapping("api/acco")额外添加了api,导致路径叠加为/api/api/acco/... - 接口路径拼写错误:
treansfer应为transfer,且路径变量前缺少斜杠,格式不合法 - 缺失Controller类定义:原代码没有类声明,Spring无法识别该控制器
修改后的Controller代码:
package com.SystemFinal.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.util.MimeTypeUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.SystemFinal.repository.AccountRepository; @RestController @RequestMapping("/acco") // 去掉重复的api,复用上下文路径的/api public class AccountController { @Autowired private AccountRepository accountRepository; @RequestMapping(value = "/transfer/{acctID}/{destAcctID}/{amount}", method = RequestMethod.PUT, produces = {MimeTypeUtils.APPLICATION_JSON_VALUE}, consumes = {MimeTypeUtils.APPLICATION_JSON_VALUE}) public ResponseEntity<Void> transferAmount(@PathVariable int acctID, @PathVariable int destAcctID, @PathVariable int amount) { try { accountRepository.saveBalanceById(acctID, destAcctID, amount); return new ResponseEntity<>(HttpStatus.OK); } catch (Exception e) { e.printStackTrace(); // 打印异常便于排查具体错误 return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } }
修正后正确请求路径:
http://localhost:8083/api/acco/transfer/1/2/20000,注意请求方式必须为PUT
2. 修复Repository层SQL语法错误
问题点:
saveBalanceById方法的SQL语句违反MySQL语法,无法在单个UPDATE语句中同时更新同一张表的两条记录
修改后的Repository方法:
@Repository("AccountRepository") public interface AccountRepository extends CrudRepository<Account, Integer>, JpaRepository<Account, Integer> { @Query(value = "select balance from acco where id=?1", nativeQuery = true) public int getBalanceById(int acc); // 拆分为两个UPDATE语句,用事务保证原子性 @Transactional @Modifying(clearAutomatically = true) @Query(value = "UPDATE acco SET balance = balance + ?3 WHERE id = ?1; " + "UPDATE acco SET balance = balance - ?3 WHERE id = ?2", nativeQuery = true) public void saveBalanceById(int id, int raccId, int amount); @Transactional @Modifying(clearAutomatically = true) @Query(value = "update acco set balance=balance-?2 where id=?1", nativeQuery = true) public void withdrawById(int id, int balance); }
优化建议(更规范的业务逻辑):
在Service层添加转账逻辑,增加余额校验,保证事务原子性:
- 在
AccountService接口新增方法:
public void transferAmount(int acctID, int destAcctID, int amount);
- 在
AccountServiceImpl实现:
@Override @Transactional public void transferAmount(int acctID, int destAcctID, int amount) { int balance = accountRepository.getBalanceById(acctID); if (balance < amount) { throw new RuntimeException("账户余额不足"); } accountRepository.withdrawById(acctID, amount); // 新增Repository存款方法 accountRepository.depositById(destAcctID, amount); }
- Repository新增存款方法:
@Transactional @Modifying(clearAutomatically = true) @Query(value = "UPDATE acco SET balance = balance + ?2 WHERE id = ?1", nativeQuery = true) public void depositById(int id, int amount);
3. 其他注意事项
- 确保请求方式为
PUT,不要用GET/POST - 检查数据库连接配置是否正确,保证
bankdb数据库存在且acco表结构与Entity匹配 - 建议使用构造注入替代
@Autowired,提高代码可测试性
内容的提问来源于stack exchange,提问作者Nuru Ahmed
相关产品推荐
相关产品推荐

