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

如何用Jackson将JSON数组反序列化为Kotlin数据类?

如何使用Jackson将JSON数组转换为指定Kotlin类?

给定如下JSON:

["answer", 42]

以及对应的Kotlin数据类:

data class JsonRow(val s: String, val n: Int)

如何使用Jackson将该数组转换为上述类?


最小可复现示例(Kotlin代码,Java场景下问题一致)

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import kotlin.test.Test
import kotlin.test.assertEquals


data class JsonRow(val s: String, val n: Int)

object Example {

    @Test
    fun example() {
        // Given
        val jsonArray = """["answer", 42]"""
        val objectMapper = jacksonObjectMapper()

        // When
        val actual = objectMapper.readValue<JsonRow>(jsonArray)

        // Then
        val expected = JsonRow("answer", 42)
        assertEquals(expected, actual)
    }
}

测试执行失败,报错信息如下:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type com.example.JsonRowfrom Array value (tokenJsonToken.START_ARRAY) at [Source: (String)"["answer", 42]"; line: 1, column: 1]


解决方案

方法1:用@JsonFormat指定数组映射规则

直接在数据类上添加注解,告诉Jackson该类需要从JSON数组反序列化,属性会按声明顺序匹配数组元素:

import com.fasterxml.jackson.annotation.JsonFormat
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import kotlin.test.Test
import kotlin.test.assertEquals

@JsonFormat(shape = JsonFormat.Shape.ARRAY)
data class JsonRow(val s: String, val n: Int)

object Example {
    @Test
    fun example() {
        val jsonArray = """["answer", 42]"""
        val objectMapper = jacksonObjectMapper()
        val actual = objectMapper.readValue<JsonRow>(jsonArray)
        val expected = JsonRow("answer", 42)
        assertEquals(expected, actual)
    }
}

方法2:用@JsonProperty自定义元素映射顺序

如果数组元素顺序和类属性声明顺序不一致,可通过注解指定每个属性对应数组的索引位置:

import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import kotlin.test.Test
import kotlin.test.assertEquals

data class JsonRow(
    @JsonProperty(index = 0) val s: String,
    @JsonProperty(index = 1) val n: Int
)

object Example {
    @Test
    fun example() {
        val jsonArray = """["answer", 42]"""
        val objectMapper = jacksonObjectMapper()
        val actual = objectMapper.readValue<JsonRow>(jsonArray)
        val expected = JsonRow("answer", 42)
        assertEquals(expected, actual)
    }
}

方法3:自定义反序列化器(处理复杂逻辑)

如果需要对数组元素做额外处理(比如类型转换、参数校验),可以自定义反序列化逻辑:

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import kotlin.test.Test
import kotlin.test.assertEquals

data class JsonRow(val s: String, val n: Int)

class JsonRowDeserializer : JsonDeserializer<JsonRow>() {
    override fun deserialize(p: JsonParser, ctxt: DeserializationContext): JsonRow {
        val array = p.readValueAsArray<String>()
        return JsonRow(array[0], array[1].toInt())
    }
}

object Example {
    @Test
    fun example() {
        val jsonArray = """["answer", 42]"""
        val module = SimpleModule().addDeserializer(JsonRow::class.java, JsonRowDeserializer())
        val objectMapper = jacksonObjectMapper().registerModule(module)
        val actual = objectMapper.readValue<JsonRow>(jsonArray)
        val expected = JsonRow("answer", 42)
        assertEquals(expected, actual)
    }
}

内容的提问来源于stack exchange,提问作者Jake

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 18:18:31