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

JsonNullable反序列化异常求助:null值时isPresent仍为true

解决JsonNullable反序列化时null值导致isPresent为true的问题

问题说明

用ObjectMapper将JSON文件/字符串反序列化为对象时,所有字段都采用JsonNullable作为包装类型。当前遇到的问题是:即便JsonNullable内部的属性值为null,它的isPresent属性仍为true,导致orElse、isPresent等方法无法正常工作,进而触发空指针异常(NPE)。需要实现:反序列化时,若JSON字段值为null,将JsonNullable的isPresent设为false。

JSON示例

{
  "id": 12345,
  "mdmCode": 12345,
  "mdmLegalStatusCode": "Enterprise",
  "nullableField": null
}

已尝试的ObjectMapper配置

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.registerModule(new Jdk8Module());
objectMapper.registerModule(new JsonNullableModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);

解决方案

默认的JsonNullableModule逻辑是:只要JSON中存在该字段(哪怕值为null),就会创建isPresent=true的JsonNullable实例。要修改这个行为,需要自定义反序列化器并替换默认配置。

1. 自定义JsonNullable反序列化器

编写一个继承JsonDeserializer的自定义类,在反序列化时判断字段值是否为null,为null则返回JsonNullable.undefined()(对应isPresent=false),否则返回正常包装的JsonNullable实例。

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import org.openapitools.jackson.nullable.JsonNullable;

import java.io.IOException;

public class CustomJsonNullableDeserializer<T> extends JsonDeserializer<JsonNullable<T>> {

    @Override
    public JsonNullable<T> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        if (node.isNull()) {
            // 字段值为null时,返回isPresent=false的JsonNullable
            return JsonNullable.undefined();
        } else {
            // 正常反序列化值,返回isPresent=true的JsonNullable
            Class<T> valueType = (Class<T>) ctxt.getContextualType().getBindings().getTypeParameters().get(0).getRawClass();
            T value = ctxt.readValue(p, valueType);
            return JsonNullable.of(value);
        }
    }
}

2. 替换默认的JsonNullable模块配置

取消注册默认的JsonNullableModule,改为注册包含自定义反序列化器的模块:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.registerModule(new Jdk8Module());

// 注册自定义JsonNullable处理模块
SimpleModule customJsonNullableModule = new SimpleModule();
customJsonNullableModule.addDeserializer(JsonNullable.class, new CustomJsonNullableDeserializer<>());
objectMapper.registerModule(customJsonNullableModule);

// 保留原有其他配置
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);

3. 效果验证

  • 当JSON字段存在且值为null时,反序列化得到的JsonNullable实例isPresent()返回false,调用orElse("默认值")会返回默认值,避免NPE。
  • 当JSON字段不存在时,仍保持原有逻辑,JsonNullable的isPresent()返回false。
  • 当JSON字段值不为null时,isPresent()返回true,get()能正常获取到对应值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:22:05