jackson 模块 kotlin 中的嵌套多态性

问题描述 投票:0回答:1

我只是想实现反序列化嵌套多态数据类,但我无法这样做。前面的问题和答案对于我完成这个看起来简单的任务没有太大帮助。无论我添加构造函数、添加更多注释等,我仍然收到此错误。非常困惑。

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `Dog` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type"
)
@JsonSubTypes(
    JsonSubTypes.Type(value = Dog::class, name = "dog"),
)
sealed class Animal(val name: String)

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type"
)
@JsonSubTypes(
    JsonSubTypes.Type(value = Labrador::class, name = "labrador")
)
sealed class Dog(name: String, val breed: String) : Animal(name)

class Labrador(name: String, val color: String) : Dog(name, "Labrador")

fun main() {
    val json = """
    {
      "type": "dog",
      "name": "Buddy",
      "breed": "Labrador",
      "color": "golden"
    }
    """

    val objectMapper = jacksonObjectMapper()
    val animal: Animal = objectMapper.readValue(json)

    println(animal.javaClass) // class com.example.Dog
    println(animal.name) // Buddy
    println((animal as Dog).breed) // Labrador
    println((animal as? Labrador)?.color) // golden
}
java json kotlin jackson
1个回答
0
投票
import com.fasterxml.jackson.annotation.*
import com.fasterxml.jackson.module.kotlin.*

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type"
)
@JsonSubTypes(
    JsonSubTypes.Type(value = Dog::class, name = "dog"),
    JsonSubTypes.Type(value = Labrador::class, name = "labrador")
)
sealed class Animal(val name: String)

// Make Dog an interface instead of a sealed class
interface Dog 

data class Labrador(val name: String, val color: String, val breed: String = "Labrador") : Animal(name), Dog

fun main() {
    val json = """
    {
      "type": "labrador",
      "name": "Buddy",
      "breed": "Labrador",
      "color": "golden"
    }
    """

    val objectMapper = jacksonObjectMapper()
    val animal: Animal = objectMapper.readValue(json)

    println(animal.javaClass) 
    println(animal.name) // Buddy
    if (animal is Labrador) {
        println(animal.breed) // Labrador
        println(animal.color) // golden
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.