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

Jackson实现必填JsonProperty校验失败,能否不修改User类?

不修改User类实现Jackson必填字段校验的方案

你遇到的问题本质是:Jackson的@JsonProperty(required = true)注解在使用无参构造器+字段直接赋值的反序列化模式下不会触发缺失校验,而Lombok生成的protected无参构造器恰好让Jackson采用了这种模式。以下两种方案可以不用修改User类实现校验需求:

方案一:启用Jackson构造器反序列化特性

通过配置ObjectMapper,强制Jackson使用Lombok生成的全参构造器进行反序列化,同时开启缺失构造器参数的失败特性:

String test = "{\"name\":\"blablabla\"}";
ObjectMapper objectMapper = new ObjectMapper();

// 开启缺失构造器必填参数时抛出异常的特性
objectMapper.enable(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES);
// 允许Jackson访问User类中protected的构造器
objectMapper.setVisibility(PropertyAccessor.CREATOR, Visibility.PROTECTED_AND_PUBLIC);

try {
    User user = objectMapper.readValue(test, User.class);
} catch (JsonMappingException e) {
    // 捕获到缺失id字段的异常,处理校验失败逻辑
    e.printStackTrace();
}

此时Jackson会尝试调用User的全参构造器,发现缺少id参数时直接抛出JsonMappingException,触发你期望的校验失败逻辑。

方案二:使用JSON Schema校验

借助Jackson的JSON Schema模块,先校验输入JSON的结构合法性,再进行反序列化:

第一步:添加依赖(Maven示例)

<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-jsonSchema</artifactId>
    <version>2.12.x</version> <!-- 与你的Jackson版本保持一致 -->
</dependency>
<dependency>
    <groupId>org.everit.json</groupId>
    <artifactId>org.everit.json.schema</artifactId>
    <version>1.14.0</version>
</dependency>

第二步:校验代码实现

String test = "{\"name\":\"blablabla\"}";
ObjectMapper objectMapper = new ObjectMapper();

// 1. 生成User类对应的JSON Schema
JsonSchemaGenerator schemaGenerator = new JsonSchemaGenerator(objectMapper);
JsonSchema schema = schemaGenerator.generateSchema(User.class);

// 2. 初始化Schema校验器
SchemaFactory schemaFactory = SchemaFactory.getInstance(SchemaVersion.DRAFT_7);
Validator validator = schemaFactory.getValidator();

// 3. 解析待校验的JSON并执行校验
JsonNode jsonNode = objectMapper.readTree(test);
Set<ValidationMessage> validationErrors = validator.validate(schema, jsonNode);

if (!validationErrors.isEmpty()) {
    // 校验失败,抛出异常或处理错误
    throw new IllegalArgumentException("JSON格式非法: " + validationErrors);
}

// 4. 校验通过后再反序列化
User user = objectMapper.readValue(test, User.class);

这种方式完全脱离实体类的反序列化逻辑,先通过Schema验证JSON结构,确保必填字段存在后再进行对象转换,彻底避免修改User类。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 14:32:14