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

如何在Jackson反序列化时忽略Null字段并使用默认值?

问题描述

我的@RequestBody类定义如下:

data class UpsertDataDto(
    @field:JsonProperty("pages")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    val links: List<Long> = emptyList()
)

为避免links字段为null时触发错误,我使用了@JsonInclude(JsonInclude.Include.NON_NULL)注解并设置默认值emptyList()。但当发送含null的请求时,出现如下异常:

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: 
JSON parse error: Instantiation of [simple type, class com.life.app.domain.dto.request.UpsertDataDto] 
value failed for JSON property links due to missing (therefore NULL) 
value for creator parameter synonyms which is a non-nullable type; 
nested exception is com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: 
Instantiation of [simple type, class com.life.app.domain.dto.request.UpsertDataDto] value 
failed for JSON property links due to missing (therefore NULL) value for creator parameter links 
which is a non-nullable type<EOL> at 
[Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 422, column: 1] 
(through reference chain: com.life.app.domain.dto.request.UpsertDataDto["pages"]->java.util.ArrayList[38]->
com.life.app.domain.dto.request.UpsertDataDto["links"])]

测试用的JSON:

{
    "links": null
}
解决方案

问题根源

@JsonInclude(NON_NULL)是序列化阶段的注解,作用是把对象转成JSON时忽略null字段,但当前场景是反序列化(JSON转对象),这个注解完全不起作用。另外Kotlin中val links: List<Long>是非空类型,当JSON明确传入"links": null时,Jackson尝试将null赋值给非空字段,直接触发类型不匹配异常。

具体解决方法

方法一:将字段设为可空类型,封装非空访问器

把links定义为可空类型,通过自定义getter确保业务逻辑中使用的是非空集合:

data class UpsertDataDto(
    @field:JsonProperty("pages")
    val links: List<Long>? = null
) {
    // 对外提供非空的安全访问字段
    val safeLinks: List<Long> get() = links ?: emptyList()
}

方法二:用@JsonSetter注解将null转为空集合

使用Jackson的@JsonSetter(nulls = Nulls.AS_EMPTY)注解,直接在反序列化时把null替换成空集合,适配非空字段(需Jackson 2.9+版本):

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

data class UpsertDataDto(
    @field:JsonProperty("pages")
    @JsonSetter(nulls = Nulls.AS_EMPTY)
    val links: List<Long> = emptyList()
)

方法三:全局配置Jackson处理null集合

如果多个DTO都有类似需求,可以在Spring中全局配置Jackson,让所有集合类型的null值自动转为空集合:

import com.fasterxml.jackson.annotation.JsonSetter
import com.fasterxml.jackson.annotation.Nulls
import com.fasterxml.jackson.module.kotlin.KotlinModule
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import com.fasterxml.jackson.databind.ObjectMapper

@Configuration
class JacksonConfig {
    @Bean
    fun objectMapper(): ObjectMapper {
        return ObjectMapper().apply {
            registerModule(KotlinModule())
            // 全局设置:将集合类型的null值转为空集合
            setDefaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY))
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:14:53