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

Spring Boot中@JsonUnwrapped+泛型继承反序列化空值校验失败问题

问题分析与解决方案

问题核心

在Spring Boot 3.4.0(Jackson 2.18.1)场景下,结合@JsonUnwrapped扁平化请求体、继承与泛型特性时,出现了**Bar1的@JsonCreator能正确解析参数,但getFoo()返回null,触发Foo1的foo1字段@NotBlank校验报错**的问题。

原因在于:@JsonUnwrapped会指示Jackson在反序列化时尝试解析父类的foo字段,但请求JSON中仅包含展开后的foo1、foo2字段,没有顶层foo字段,导致Jackson将foo字段覆盖为null,抵消了你在构造器中通过super(bar1, new Foo1(foo1, foo2))初始化的值。

解决方案(无需自定义反序列化器)

只需调整@JsonUnwrapped的配置,让它仅在序列化阶段生效,反序列化阶段忽略该字段,避免Jackson覆盖手动初始化的foo实例。

方案1:修改@JsonUnwrapped的反序列化开关

修改AbstractBar类中的foo字段注解:

public abstract class AbstractBar<F extends AbstractFoo> {

    @Pattern(regexp = "\\d{2}")
    protected final String bar1;

    @Valid
    @JsonUnwrapped(deserialization = false) // 仅序列化时展开,反序列化不处理该字段
    protected final F foo;

    // 构造器、getter方法不变
}

方案2:添加@JsonProperty(access = READ_ONLY)

通过标记字段为只读,让Jackson仅在序列化时处理它:

public abstract class AbstractBar<F extends AbstractFoo> {

    @Pattern(regexp = "\\d{2}")
    protected final String bar1;

    @Valid
    @JsonUnwrapped
    @JsonProperty(access = JsonProperty.Access.READ_ONLY) // 反序列化时忽略该字段
    protected final F foo;

    // 构造器、getter方法不变
}

验证效果

修改后重新发送请求,Jackson会通过@JsonCreator构造器正确创建Bar1实例,父类的foo字段将保持构造器中初始化的Foo1对象,getFoo()不再返回null,foo1的@NotBlank校验也能正常通过。

内容的提问来源于stack exchange,提问作者Nathan S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 22:14:53