You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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会先尝试实例化你的AppState record,虽然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中添加:
    spring.jackson.deserialization.fail-on-missing-creator-properties=false
    
    这个配置会让Jackson在缺少Record组件的情况下,用null值填充并创建对象,后续Validation的@NotNull就能正常工作,返回400。

另外,你也可以尝试在控制器方法参数上用@Validated代替@Valid,虽然两者核心功能类似,但@Validated是Spring原生提供的校验注解,在这种场景下可能更稳定地触发校验逻辑。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 09:58:09