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
相关产品推荐
相关产品推荐

