React调用SpringBoot注册接口报400错误的原因排查
问题场景
- SpringBoot后端注册接口通过Postman测试正常,但React前端调用时返回400错误
- 后端IntelliJ日志显示警告:
WARN 1264 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public org.springframework.http.ResponseEntity<com.msys.smartkart.config.GenericResponseDto> com.msys.smartkart.controller.UserController.addUser(com.msys.smartkart.entity.User) throws java.lang.Exception].
后端接口代码
@GetMapping("/register") public ResponseEntity<GenericResponseDto> addUser(@RequestBody User user) throws Exception { final boolean isNotExists = userService.findUserByEmailAddress(user.getEmailAddress()); if (isNotExists) { userService.registerUser(user); log.info("User saved successfully"); } else { log.warn("User is Already exists"); throw new Exception(user.getEmailAddress() + "Already Exists"); } return new ResponseEntity<>(new GenericResponseDto(200, "User Registered"), HttpStatus.ACCEPTED); }
React前端请求代码
const submitHandler = () => { fetch( `http://localhost:8080/register?` + new URLSearchParams({ name: name, emailAddress: emailAddress, mobileNumber: mobileNumber, password: password, confirmPassword: confirmPassword, address: address, }) ) .then((response) => response.json()) .then((res) => { if (res.statusCode === 200) { console.log(res); console.log(res.responseData); setData(res.responseData); } else { alert("Somthing went wrong try again"); } }); };
错误原因
请求方式与参数接收逻辑冲突
后端接口用@GetMapping注解,但同时使用@RequestBody获取参数。HTTP规范中GET请求通常不携带请求体,后端期望从请求体解析User对象,自然会提示"请求体缺失"。你用Postman测试正常,大概率是测试时用了POST请求并在Body中传了JSON数据,而非GET请求。前后端参数传递方式不匹配
前端通过URL查询字符串(?key=value)传递参数,但后端要求从请求体的JSON中解析User对象,两者传递路径完全不一致,导致后端无法获取所需数据。
修复方案
后端修改
将@GetMapping("/register")改为@PostMapping("/register"),注册属于创建资源的操作,符合POST请求语义,且POST支持携带请求体:
@PostMapping("/register") public ResponseEntity<GenericResponseDto> addUser(@RequestBody User user) throws Exception { // 原有业务逻辑保持不变 }
前端修改
调整fetch请求为POST方法,将参数以JSON格式放入请求体,并设置正确的请求头:
const submitHandler = () => { fetch('http://localhost:8080/register', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name: name, emailAddress: emailAddress, mobileNumber: mobileNumber, password: password, address: address, // 注意:后端接口未使用confirmPassword,可根据实际需求决定是否传递 }) }) .then((response) => response.json()) .then((res) => { if (res.statusCode === 200) { console.log(res); console.log(res.responseData); setData(res.responseData); } else { alert("Something went wrong try again"); } }) .catch(error => { console.error('请求错误:', error); alert("请求失败,请重试"); }); };
内容的提问来源于stack exchange,提问作者shiva shanker

