使用Jackson反序列化JSON为Kotlin数据类时如何实现属性类型转换
Jackson直接反序列化字符串数字到Long类型的实现方案
你不需要编写中间数据类+扩展函数做二次转换,以下三种方案都可以直接实现目标,按改动成本从低到高排列:
- 方案1:单字段加注解(仅需处理个别字段时用)
直接在id字段上加注解,指定Jackson按字符串格式读取数值,代码改动极小:
import com.fasterxml.jackson.annotation.JsonFormat data class Example( val name: String, val age: Int, @JsonFormat(shape = JsonFormat.Shape.STRING) val id: Long )
加完注解后直接用原ObjectMapper反序列化即可,Jackson会自动把字符串格式的数字解析为Long类型。
- 方案2:全局配置(项目有大量同类场景时用)
如果项目中存在大量字符串格式数字需要转数值类型的场景,不用逐字段加注解,直接修改ObjectMapper配置即可一劳永逸:
import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.KotlinModule val objectMapper = ObjectMapper().apply { // 先注册Kotlin模块,保证Kotlin数据类的基础反序列化能力 registerModule(KotlinModule.Builder().build()) // 开启后自动将JSON中合法数字格式的字符串解析为对应数值类型(Long/Int/Double等) enable(DeserializationFeature.ACCEPT_STRING_AS_NUMBER) }
配置完成后,你定义的id为Long类型的Example类可以直接用来反序列化目标JSON,不需要其他额外处理。
- 方案3:自定义反序列化器(有特殊转换规则时用)
如果id字段存在特殊格式(比如带前缀、需要先做内容清洗再转Long),可以自定义反序列化逻辑,支持单字段使用或者全局生效:
import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.DeserializationContext import com.fasterxml.jackson.databind.JsonDeserializer import com.fasterxml.jackson.databind.annotation.JsonDeserialize // 自定义字符串转Long的逻辑 class SafeStringToLongDeserializer : JsonDeserializer<Long>() { override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Long { // 这里可以加你需要的自定义清洗逻辑,比如去掉非数字字符、空值兜底等 return p.valueAsString.trim().toLong() } } // 单字段使用方式 data class Example( val name: String, val age: Int, @JsonDeserialize(using = SafeStringToLongDeserializer::class) val id: Long )
如果需要全局生效,把这个反序列化器注册到ObjectMapper的模块中即可,所有Long类型字段都会自动走这套转换逻辑。
以上三种方案都跳过了中间数据类转换的步骤,直接在反序列化阶段完成类型转换,性能比二次转换更高,代码维护成本也更低。
内容的提问来源于stack exchange,提问作者user15708369
相关产品推荐
相关产品推荐

