Spring Boot接收Postman POST请求返回400,反序列化异常求助
问题修复方案
你遇到的两个报错都属于Jackson反序列化阶段的类型匹配问题,修复方法如下:
1. 日期格式反序列化错误修复
报错原因:SpringBoot默认使用Jackson做JSON序列化/反序列化,java.util.Date类型默认支持的格式是带T分隔符的ISO格式,和你请求里传的yyyy-MM-dd HH:mm:ss格式不匹配,导致解析失败。
两种修复方案选一个即可:
- 字段级配置(仅对单个字段生效)
在Schedule类的date字段上添加@JsonFormat注解指定格式和时区:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date date;
- 全局配置(对项目所有Date类型生效)
在application.properties配置文件中添加如下配置:
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss spring.jackson.time-zone=GMT+8
如果用yml配置则是:
spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8
2. 关联实体反序列化错误修复
报错原因:你请求中传的driver:1、vehicule:1都是数字类型的ID值,但是Schedule类中这两个字段是Staff、Vehicule实体类型,Jackson默认没有办法直接把数字转成对应的实体对象。
推荐两种修复方案:
- 方案1:给关联实体添加ID构造方法
分别给Staff、Vehicule类添加接收ID参数的构造方法,同时保留无参构造(JPA必须要有无参构造):
// Vehicule类新增 public Vehicule() {} public Vehicule(Long id) { this.id = id; } // Staff类新增 public Staff() {} public Staff(Long id) { this.id = id; }
这个方案简单,但仅适合你不需要校验ID合法性、直接关联已有数据的场景。
- 方案2:使用DTO接收请求(更规范,推荐)
不要直接用JPA实体类作为接口的入参,单独定义ScheduleDTO类接收请求参数:
public class ScheduleDTO { private Date date; private String start; private String destination; private String provider; private Long driver; private Long vehicule; // 补充getter、setter方法 }
Controller层用DTO接收参数后,再转换为Schedule实体,从数据库查询对应的driver和vehicule对象后赋值:
@PostMapping(value="/schedule/create") public String createSchedule(@RequestBody ScheduleDTO dto) { Schedule schedule = new Schedule(); schedule.setDate(dto.getDate()); schedule.setStart(dto.getStart()); schedule.setDestination(dto.getDestination()); schedule.setProvider(dto.getProvider()); // 查询关联对象,可自行补充ID不存在的异常处理逻辑 Staff driver = staffRepository.findById(dto.getDriver()).orElseThrow(() -> new RuntimeException("司机不存在")); Vehicule vehicule = vehiculeRepository.findById(dto.getVehicule()).orElseThrow(() -> new RuntimeException("车辆不存在")); schedule.setDriver(driver); schedule.setVehicule(vehicule); return scheduleService.addSchedule(schedule); }
这个方案可以提前做参数校验、避免暴露实体的敏感字段,更符合分层开发规范。
额外注意点
你Schedule类中的Start字段首字母大写,但是请求里传的是小写的start,Jackson默认按照驼峰命名匹配,会导致该字段接收不到值,要么把字段名改成小写private String start;,要么给字段加@JsonProperty("start")注解。
内容的提问来源于stack exchange,提问作者wael
相关产品推荐
相关产品推荐

