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

Jackson Kotlin忽略Null值失效:setSerializationInclusion不生效问题

Kotlin Jackson反序列化忽略Null值并保留默认值

问题背景

需要在JSON反序列化时,将字段的Null值忽略,直接使用字段定义的默认值填充,但不想把字段设为可空类型——程序逻辑中该值不允许为Null,仅为兼容旧版本数据才需要处理JSON中的Null值。

尝试使用setSerializationInclusion(JsonInclude.Include.NON_NULL)全局配置,以及在字段上添加@JsonInclude(JsonInclude.Include.NON_NULL)注解,均无效果。执行示例代码时抛出NullPointerException: Parameter specified as non-null is null: method icu.samnyan.aqua.spring.TestA.setS, parameter <set-?>,无法正常解析。

复现代码

import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.databind.ObjectMapper

val JACKSON = ObjectMapper().apply {
    setSerializationInclusion(JsonInclude.Include.NON_NULL)
    setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL)
}

class TestA {
    @JsonInclude(JsonInclude.Include.NON_NULL)
    var s: String = ""
}

fun main() {
    println(JACKSON.readValue("""{"s":null}""", TestA::class.java).toString())
}

核心问题

JsonInclude.Include.NON_NULL是序列化阶段的配置,作用是将对象转为JSON时忽略值为Null的字段,完全不影响反序列化逻辑。反序列化时,Jackson会尝试把JSON中的Null值赋值给非可空字段,而Kotlin的非可空字段setter会校验参数非空,因此抛出空指针异常。

解决方案

方案1:字段级注解控制

在字段上添加@JsonSetter(nulls = Nulls.SKIP)注解,指定当字段值为Null时跳过赋值,保留字段默认值:

import com.fasterxml.jackson.annotation.JsonSetter
import com.fasterxml.jackson.annotation.Nulls
import com.fasterxml.jackson.databind.ObjectMapper

val JACKSON = ObjectMapper()

class TestA {
    @JsonSetter(nulls = Nulls.SKIP)
    var s: String = ""
}

fun main() {
    println(JACKSON.readValue("""{"s":null}""", TestA::class.java).s) // 输出:""
}

方案2:全局配置统一处理

如果需要批量处理所有非可空字段,可通过全局配置让Jackson在反序列化时跳过Null值的赋值操作:

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import com.fasterxml.jackson.annotation.JsonSetter
import com.fasterxml.jackson.annotation.Nulls

val JACKSON = ObjectMapper().apply {
    // 注册Kotlin模块,更好支持Kotlin特性
    registerKotlinModule()
    // 配置全局setter处理Null值的策略:跳过赋值
    setDefaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.SKIP))
    // 可选:允许基本类型接收Null值(如果有基本类型字段需要处理)
    configure(DeserializationFeature.ACCEPT_NULL_FOR_PRIMITIVES, true)
}

class TestA {
    var s: String = ""
}

fun main() {
    println(JACKSON.readValue("""{"s":null}""", TestA::class.java).s) // 输出:""
}

关键说明

  • 区分序列化和反序列化配置:JsonInclude.NON_NULL只影响对象转JSON的过程,和JSON转对象的反序列化无关。
  • Kotlin非可空字段的setter自带非空校验,必须显式配置Jackson跳过Null值赋值,才能保留字段默认值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 15:17:11