SpringBoot中PUT请求插入对象时日期字段为null的问题
问题概述
使用SpringBoot开发后端时,GET、POST请求均正常,但发送带日期的PUT请求时,loan_start、loan_returned字段到达Controller时为null,触发数据库非空约束报错(Postman返回500,日志提示NULL not allowed for column "LOAN_RETURNED")。相关代码结构:Controller的PUT接口接收LoanDto,通过BeanUtils.copyProperties复制到Loan实体后保存,LoanDto与Loan结构完全一致。
解决方案
1. 给LoanDto的日期字段添加反序列化注解
实体类上的@JsonFormat仅用于序列化(后端返回前端),反序列化(前端传参到Dto)需要在LoanDto的日期字段上同样配置注解,确保Jackson能正确解析JSON中的日期字符串:
// LoanDto中的日期字段配置 @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate loan_start; @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate loan_returned;
或者使用@DateTimeFormat配合:
@DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate loan_start;
2. 确认请求的Content-Type
Postman发送PUT请求时,务必将Content-Type设置为application/json。如果误设为form-data或其他类型,会导致JSON反序列化失败,日期字段无法被解析。
3. 排查BeanUtils复制前的Dto状态
在Controller中添加日志,确认LoanDto的日期字段是否真的为null:
@RequestMapping(path = { "" }, method = RequestMethod.PUT) public void save(@RequestBody LoanDto dto) { // 打印日志确认字段值 System.out.println("loan_start: " + dto.getLoan_start()); System.out.println("loan_returned: " + dto.getLoan_returned()); this.loanService.save(dto); }
如果Dto中字段已为null,说明问题出在反序列化阶段,优先解决注解配置问题。
4. 检查Spring Boot与Java 21的兼容性
确保使用Spring Boot 3.x及以上版本(Spring Boot 3.x原生支持Java 17+),旧版本可能存在Java 21下LocalDate反序列化的兼容性问题。
5. 字段命名与JSON映射匹配
下划线命名的字段(如loan_start)可能存在Jackson自动映射的偏差,可以通过@JsonProperty明确指定JSON字段名:
@JsonProperty("loan_start") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate loan_start;
或者将字段改为驼峰式(loanStart),同时请求体中的字段对应改为"loanStart": "2023-01-04"。
内容的提问来源于stack exchange,提问作者Miguel Angel Guaita

