如何配置Jackson序列化实现集合接口的Kotlin数据类所有字段?
Kotlin委托实现List接口的数据类Jackson序列化问题解决
问题场景
我们有一个通过委托实现List<Item>接口的Kotlin数据类:
data class StockList( val lastModified: Instant, val items: List<Item> ) : List<Item> by items
使用Jackson(版本2.15.0,搭配jackson-module-kotlin)序列化时,输出结果仅包含items的列表内容,丢失了lastModified属性:
[ {"id":"B1","name":"banana","sellByDate":"2021-10-28","quality":42,"price":null}, {"id":"K1","name":"kumquat","sellByDate":null,"quality":101,"price":null} ]
但移除List<Item>接口实现后,序列化就能正常输出所有属性。我们需要让Jackson将StockList视为普通类而非集合实现来序列化。
解决方案
方案1:使用@JsonSerialize注解指定序列化类型
在StockList类上添加@JsonSerialize(as = Object::class)注解,明确告诉Jackson将该类当作普通对象序列化,而非集合:
import com.fasterxml.jackson.databind.annotation.JsonSerialize import java.time.Instant @JsonSerialize(as = Object::class) data class StockList( val lastModified: Instant, val items: List<Item> ) : List<Item> by items
此时序列化结果会包含所有属性:
{ "lastModified":"2022-02-09T23:59:59Z", "items": [ {"id":"B1","name":"banana","sellByDate":"2021-10-28","quality":42,"price":null}, {"id":"K1","name":"kumquat","sellByDate":null,"quality":101,"price":null} ] }
方案2:全局配置ObjectMapper禁用集合类型自动检测
如果需要对所有类似场景生效,可以在初始化ObjectMapper时禁用AUTO_DETECT_COLLECTION_TYPES特性:
import com.fasterxml.jackson.databind.MapperFeature import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper val objectMapper = jacksonObjectMapper() .disable(MapperFeature.AUTO_DETECT_COLLECTION_TYPES)
注意:这是全局配置,会影响所有类的序列化行为,需根据实际需求选择。
方案3:自定义序列化器(进阶)
如果需要更精细的控制,可以为StockList编写自定义序列化器:
import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.databind.SerializerProvider import com.fasterxml.jackson.databind.ser.std.StdSerializer import java.time.Instant class StockListSerializer : StdSerializer<StockList>(StockList::class.java) { override fun serialize(value: StockList, gen: JsonGenerator, provider: SerializerProvider) { gen.writeStartObject() gen.writeStringField("lastModified", value.lastModified.toString()) gen.writeFieldName("items") provider.defaultSerializeValue(value.items, gen) gen.writeEndObject() } }
然后在类上指定该序列化器:
import com.fasterxml.jackson.databind.annotation.JsonSerialize @JsonSerialize(using = StockListSerializer::class) data class StockList( val lastModified: Instant, val items: List<Item> ) : List<Item> by items
这种方式适合需要自定义输出格式的场景。
内容的提问来源于stack exchange,提问作者Duncan McGregor
相关产品推荐
相关产品推荐

