Kotlin中Map<String, Double>字段JSON序列化失败问题排查
问题描述
定义了如下Kotlin数据类:
data class MyClass(private val myMap: Map<String, Double>, val defaultValue: Double)
将JSON反序列化为该类实例时正常,但将实例序列化为JSON时,myMap字段无法输出。测试代码如下:
private val objectMapper: ObjectMapper = jacksonObjectMapper().findAndRegisterModules() @Test fun serializing() { val myClass = MyClass(mapOf(Pair("user1",1.0), Pair("user2", 2.0)), defaultValue = 1.0) val myMapObject = JSONObject() myMapObject.put("user1",1) myMapObject.put("user2",2) val expected= JSONObject() expected.put("myMap", myMapObject) expected.put("defaultValue", 1) val actual = JSONObject(this.objectMapper.writeValueAsString(myClass)) assertEquals(expected, actual) }
实际生成的JSON仅为{"defaultValue":1},myMap字段缺失。
问题原因及解决办法
核心原因:Jackson默认只序列化类的公共可访问属性(公共字段或带公共getter的私有字段)。
myMap是私有val,没有对应的公共getter方法,Jackson无法识别并序列化该字段。反序列化正常是因为Jackson可以通过构造方法注入私有字段,但序列化时需要读取字段的权限。解决办法:
- 修改字段可见性(最简单直接):去掉
myMap的private修饰符,让它成为公共字段:data class MyClass(val myMap: Map<String, Double>, val defaultValue: Double) - 保留私有但添加注解:给
myMap加上@JsonProperty注解,强制Jackson序列化该字段:import com.fasterxml.jackson.annotation.JsonProperty data class MyClass(@JsonProperty private val myMap: Map<String, Double>, val defaultValue: Double) - 全局配置ObjectMapper(不推荐,会序列化所有私有字段):修改ObjectMapper的可见性规则,允许访问私有字段:
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility import com.fasterxml.jackson.databind.PropertyAccessor private val objectMapper: ObjectMapper = jacksonObjectMapper() .findAndRegisterModules() .setVisibility(PropertyAccessor.FIELD, Visibility.ANY)
- 修改字段可见性(最简单直接):去掉
另外注意:测试代码中最后一行的pointCalculator是笔误,应该改为myClass,否则会引用未定义的变量导致测试失败。
内容的提问来源于stack exchange,提问作者Manuelarte
相关产品推荐
相关产品推荐

