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

