Vite+React通过Axios调用SpringBoot单产品API出现400错误
问题描述
- 环境:Vite+React前端,SpringBoot后端,使用Axios进行接口调用
- 异常现象:
- 直接访问后端接口
http://localhost:8080/api/products/1可正常返回数据 - 前端调用时返回400错误,控制台输出
Error fetching product: AxiosError - 后端报错日志:
Failed to convert value of type 'java.lang.String' to required type 'int'; For input string: "NaN"
- 直接访问后端接口
相关代码信息
前端代码
Product.jsx:通过useParams获取路由参数id并转为int类型,在useEffect钩子中发起Axios请求- 路由配置:包含
/products和/products/:id两个路由,均指向Product组件
后端代码
ProductController:getProduct接口接收int类型的@PathVariable参数idProduct实体类:productID字段为int类型- Service层:通过
repo.findById(id)执行数据查询
解决方案
核心原因
前端传递给后端的id参数为NaN,导致后端无法将字符串"NaN"转换为int类型,触发400错误。根源是两个路由共用同一个Product组件,当访问/products(无id参数)时,useParams获取不到有效id,转换为int后得到NaN,此时发起请求就会传递非法参数。
具体修复步骤
- 前端增加参数校验
在发起Axios请求前,先校验id的有效性,仅当参数合法时执行请求:
import { useParams, useEffect } from 'react'; import axios from 'axios'; function Product() { const { id } = useParams(); const productId = parseInt(id, 10); useEffect(() => { // 校验id是否为有效正整数 if (!isNaN(productId) && productId > 0) { axios.get(`/api/products/${productId}`) .then(res => { // 处理返回数据逻辑 }) .catch(err => { console.error('Error fetching product:', err); }); } }, [productId]); // 组件其他逻辑 } export default Product;
- 拆分路由组件(可选优化)
如果/products是产品列表页,建议将列表和详情逻辑拆分为两个独立组件,避免同一组件处理不同场景:
// 路由配置示例 import { Routes, Route } from 'react-router-dom'; import ProductList from './ProductList'; import ProductDetail from './ProductDetail'; function App() { return ( <Routes> <Route path="/products" element={<ProductList />} /> <Route path="/products/:id" element={<ProductDetail />} /> </Routes> ); }
拆分后ProductDetail仅处理详情查询,无需额外校验id是否存在。
- 后端增加兜底校验
在ProductController中增加参数合法性校验,避免非法参数导致异常:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; import org.springframework.http.HttpStatus; @RestController public class ProductController { private final ProductService productService; public ProductController(ProductService productService) { this.productService = productService; } @GetMapping("/api/products/{id}") public Product getProduct(@PathVariable int id) { if (id <= 0) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "无效的产品ID"); } return productService.getProductById(id); } }
内容的提问来源于stack exchange,提问作者Shristi
相关产品推荐
相关产品推荐

