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:
- 修改React组件的
useState初始化,给cat初始化空对象:
const [product, setProduct] = useState({ prodName: "", prodDes: "", prodQunt: "", cat: {} });
- 修改
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 }); } }
- 调整下拉选择框的
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接收参数,再转换为实体类:
- 创建
ProductDTO类,用于接收前端参数:
@Data public class ProductDTO { private String prodName; private String prodDes; private int prodQunt; private Long catId; // 接收分类ID }
- 修改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); } }
- 前端下拉选择框的
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
相关产品推荐
相关产品推荐

