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

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可以通过构造方法注入私有字段,但序列化时需要读取字段的权限。

  • 解决办法:

    1. 修改字段可见性(最简单直接):去掉myMap的private修饰符,让它成为公共字段:
      data class MyClass(val myMap: Map<String, Double>, val defaultValue: Double)
      
    2. 保留私有但添加注解:给myMap加上@JsonProperty注解,强制Jackson序列化该字段:
      import com.fasterxml.jackson.annotation.JsonProperty
      
      data class MyClass(@JsonProperty private val myMap: Map<String, Double>, val defaultValue: Double)
      
    3. 全局配置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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:12:14