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

Spring Boot自定义ObjectMapper反序列化对象验证失效问题排查

解决方案:保留Lombok注解同时触发JSR380反序列化校验

问题根源在于@Value + @Builder + @Jacksonized的组合下,Jackson通过Builder模式实例化对象,默认的JSR380校验只会在最终对象创建后执行,但此时Builder已经将null值传入不可变对象(@Value生成的类是不可变的),导致校验失效。以下是具体解决步骤:

1. 给模型类的Builder添加校验触发注解

在每个使用@Builder的模型类中,给自动生成的Builder内部类添加@Builder.Valid注解,让校验器在对象构建前就校验Builder的属性:

Address类示例

@Value
@Builder(toBuilder = true)
@Jacksonized
public class Address {
    @NotNull
    private final String addrName;

    // 给Builder添加@Builder.Valid,触发构建前校验
    @Builder.Valid
    public static class AddressBuilder {}
}

Student类示例(注意嵌套对象的@Valid)

如果Student包含Address这类嵌套对象,必须给嵌套字段添加@Valid,确保嵌套对象的校验能被递归触发:

@Value
@Builder(toBuilder = true)
@Jacksonized
public class Student {
    @NotNull
    private final String name;
    
    @Valid // 递归校验嵌套的Address对象
    @NotNull
    private final Address address;

    @Builder.Valid
    public static class StudentBuilder {}
}

2. 配置Jackson的ValidationModule为校验Builder模式

自定义ObjectMapper时,要明确设置ValidationModule的校验模式为VALIDATE_BUILDER,让校验器针对Builder实例而非最终对象执行校验:

// 初始化JSR380校验器
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();

// 配置Jackson的ValidationModule
ValidationModule validationModule = new ValidationModule();
validationModule.setValidator(validator);
// 关键:设置校验时机为构建对象前校验Builder
validationModule.setValidationMode(ValidationModule.ValidationMode.VALIDATE_BUILDER);

// 注册模块到ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(validationModule);
// 其他Jackson配置(如序列化/反序列化规则)...

为什么@JsonProperty(required = true)无效?

@JsonProperty(required = true)仅作用于Jackson的反序列化规则:当JSON中完全缺失该字段时抛出异常,但如果JSON中明确传递了null值,这个注解不会触发校验逻辑,而@NotNull是JSR380的校验规则,必须通过校验器才能生效。

内容的提问来源于stack exchange,提问作者Trilochan Badhei

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:05:18