鉴于此 JSON,
["answer", 42]
以及伴随课程,
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.JsonRow` from Array value (token `JsonToken.START_ARRAY`) at [Source: (String)"["answer", 42]"; line: 1, column: 1]
使用自定义解串器来完成此操作是可能的,但非常不优雅。
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
@JsonDeserialize(using = JsonRowDeserializer::class)
data class JsonRow(val s: String, val n: Int)
class JsonRowDeserializer : StdDeserializer<JsonRow>(JsonRow::class.java) {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): JsonRow {
val (s, n) = p.readValueAs(Array::class.java)
return JsonRow(s as String, n as Int)
}
}