Spring Boot REST POST接口@RequestBody接收DTO对象为null问题
Spring Boot接口@RequestBody接收DTO始终为null排查思路
快速定位根因方法
先在配置文件中添加如下配置,开启Web层DEBUG日志,重启后发起请求,查看控制台输出的反序列化报错信息,可直接定位具体失败原因:
logging.level.org.springframework.web.servlet.mvc.method.annotation=DEBUG logging.level.com.fasterxml.jackson.databind=DEBUG
常见问题排查点
- DTO基础结构不符合Jackson反序列化要求
贴出的QuestionnaireDTORequest类仅定义了字段,未提供无参构造方法、各字段的getter/setter方法。Spring Boot默认使用Jackson做JSON反序列化,要求目标类必须存在无参构造,且所有需要赋值的字段有可访问的setter方法,否则无法完成字段填充,直接导致反序列化失败、参数为null。不想手写模板代码可直接在DTO类上添加Lombok的
@Data注解,自动生成无参构造、getter、setter等方法,注意提前在IDEA中安装Lombok插件避免编译报错。 - 布尔类型字段命名不匹配
DTO中定义了基本布尔类型字段private boolean isActive = false;,如果使用IDEA自动生成getter/setter,生成的方法会是isActive()、setActive(),Jackson默认会将setter方法去掉set前缀、首字母小写后匹配JSON字段,也就是会匹配active字段,和传入的isActive字段名不匹配,导致赋值失败。修复方案二选一:要么将字段名修改为
private boolean active;,请求体对应传"active": false;要么在isActive字段上添加@JsonProperty("isActive")注解,明确指定Jackson匹配的JSON字段名。 - 时间类型反序列化配置缺失
DTO中createdDate为LocalDate类型,传入的日期格式为yyyy-MM-dd,如果项目未引入JSR310时间序列化模块、未配置对应日期格式,Jackson无法将时间字符串转为LocalDate对象,会导致整个反序列化流程失败。修复方案:给
createdDate字段添加@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")注解;如果是Spring Boot 2.0以下版本,需要额外引入jackson-datatype-jsr310依赖。 - Postman请求配置错误
确认Postman发送请求时,Body栏选择raw模式,右侧格式下拉选项选中JSON,否则请求头不会自动携带Content-Type: application/json,Spring不会调用JSON消息转换器解析请求体。另外要检查请求体是否携带BOM头、前后多余不可见字符,可将请求体复制到纯文本编辑器清理后重新粘贴发送。 - 嵌套对象不满足反序列化要求
请求体中嵌套的questionSet数组对应DTO中的Set<Question>类型,需要确认Question类同样满足反序列化规则:存在无参构造、text、possibleAnswerSet字段有对应getter/setter;如果Question是DTO的内部类,必须加static修饰,否则Jackson无法实例化嵌套对象,导致整体反序列化失败。 - 请求体被提前读取
如果项目中自定义了过滤器、拦截器、切面,在请求进入控制器之前就通过request.getInputStream()读取过请求体内容,由于Servlet输入流仅能读取一次,后续Spring消息转换器将无法读取到请求内容,导致反序列化得到null。该场景可通过在过滤器中用
ContentCachingRequestWrapper包装原生Request,实现请求体可重复读取即可修复。
内容的提问来源于stack exchange,提问作者Syed Iftekharuddin
相关产品推荐
相关产品推荐

