Spring Boot 3.4.7中@Valid处理空JSON请求体的行为变更问题咨询
Spring Boot 3.4.7中@Valid处理空JSON请求体的行为变更问题咨询
我太懂你这种升级后遇到诡异行为变化的感受了——从Spring Boot 3.4.6升级到3.4.7,同样是空JSON请求体,原本老老实实返回400参数错误,现在直接变成500内部错误,换谁都会懵。
咱们先拆解下为什么会出现这个差异:
- 在3.4.6及更早版本里,当你发送
{}这样的空JSON时,Jackson会先尝试实例化你的AppStaterecord,虽然state字段是null,但record本身能被创建出来。紧接着Validation层的@NotNull校验会触发,发现违反约束,Spring MVC会把这个异常转换成400 Bad Request返回给你。 - 但到了3.4.7,Jackson和Validation的协同逻辑有了调整:Java Record的默认反序列化行为是要求所有组件都必须在JSON中存在,当你发送空JSON时,Jackson直接抛出了实例化失败的异常(比如
InvalidDefinitionException),这个异常并没有被Validation的拦截器捕获,直接冒泡到了Spring的全局异常处理器,所以返回了500而不是预期的400。
你提到官方文档说Validation行为有变化,但没明确说@Valid的变更,其实这个问题本质是Jackson反序列化的错误优先级超过了Validation校验,导致Validation根本没机会执行。
给你两个可行的解决方案:
- 方案一:给Record的字段添加
@JsonProperty(required = false),告诉Jackson这个字段不是必须在JSON中存在,允许反序列化时用null填充。这样Jackson就能成功创建AppState对象,之后@NotNull校验就会正常触发,返回400错误。@Builder @Validated public record AppState( @NotNull(message = "required field") @JsonProperty(required = false) Boolean state ) {} - 方案二:全局调整Jackson的反序列化配置,允许空JSON创建Record对象。在
application.properties中添加:
这个配置会让Jackson在缺少Record组件的情况下,用null值填充并创建对象,后续Validation的spring.jackson.deserialization.fail-on-missing-creator-properties=false@NotNull就能正常工作,返回400。
另外,你也可以尝试在控制器方法参数上用@Validated代替@Valid,虽然两者核心功能类似,但@Validated是Spring原生提供的校验注解,在这种场景下可能更稳定地触发校验逻辑。
内容来源于stack exchange
相关产品推荐
相关产品推荐

