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

Spring Boot+React项目POST请求失败:无法反序列化Category对象

Spring Boot + React POST请求写入数据库失败问题解决

错误信息

"JSON parse error: Cannot construct instance of com.xx.xx.Category (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('4')"

问题根源

前端提交的cat字段是字符串类型的分类ID(如'4'),但后端Product实体中cat是Category对象,Jackson序列化框架无法直接将字符串ID转换为Category实例,导致反序列化失败。


解决方案一:前端调整提交数据结构

让前端提交包含id的cat对象,而非直接传字符串ID:

  1. 修改React组件的useState初始化,给cat初始化空对象:
const [product, setProduct] = useState({ prodName: "", prodDes: "", prodQunt: "", cat: {} });
  1. 修改handleChange方法,处理分类字段时构造对象:
const handleChange = (e) => {
    const name = e.target.name;
    const value = e.target.value;
    if (name === 'cat') {
        setProduct({ ...product, [name]: { id: value } });
    } else {
        setProduct({ ...product, [name]: value });
    }
}
  1. 调整下拉选择框的value绑定为product.cat.id:
<Form.Select name='cat' id='' onChange={handleChange} value={product.cat.id || ''}>
    {catList.map((cat) => {
        return (
            <option key={cat.id} value={cat.id}>
                {cat.catName}
            </option>
        );
    })}
</Form.Select>

解决方案二:后端通过DTO接收ID并手动关联

如果不想修改前端逻辑,可在后端创建DTO接收参数,再转换为实体类:

  1. 创建ProductDTO类,用于接收前端参数:
@Data
public class ProductDTO {
    private String prodName;
    private String prodDes;
    private int prodQunt;
    private Long catId; // 接收分类ID
}
  1. 修改Controller,注入CategoryRepository,手动查询分类并关联:
@RestController
@RequestMapping("/prods")
@CrossOrigin(origins = "http://localhost:3000")
public class ProductController {

    @Autowired
    private ProductRepository pr;
    @Autowired
    private CategoryRepository categoryRepository;
        
    @PostMapping("/add")
    public Product addProd(@RequestBody ProductDTO prodDTO) {
        Product product = new Product();
        product.setProdName(prodDTO.getProdName());
        product.setProdDes(prodDTO.getProdDes());
        product.setProdQunt(prodDTO.getProdQunt());
        
        // 根据ID查询分类,不存在则抛出异常
        Category category = categoryRepository.findById(prodDTO.getCatId())
                .orElseThrow(() -> new RuntimeException("指定分类不存在"));
        product.setCat(category);
        
        return pr.save(product);
    }
}
  1. 前端下拉选择框的name改为catId,对应DTO字段:
<Form.Select name='catId' id='' onChange={handleChange} value={product.catId || ''}>
    {catList.map((cat) => {
        return (
            <option key={cat.id} value={cat.id}>
                {cat.catName}
            </option>
        );
    })}
</Form.Select>

内容的提问来源于stack exchange,提问作者Tony

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:24:57