【问题标题】:Deserializing object to data class that contains delegated properties (inheritance with delegation)将对象反序列化为包含委托属性的数据类(带委托的继承)
【发布时间】:2021-06-26 19:46:36
【问题描述】:

您的问题 我检查了问题和文档,但找不到解决方案。

以下代码正确地将对象 (Component) 序列化为字符串,但从字符串反序列化回 Component 的实例不起作用。

在不取消委托的情况下如何做到这一点有什么建议吗?

谢谢:)


import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonSubTypes.Type
import com.fasterxml.jackson.annotation.JsonTypeInfo
import com.fasterxml.jackson.core.json.JsonReadFeature
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type"
)
@JsonSubTypes(
    value = [
        Type(value = Space::class, name = Space.TYPE),
        Type(value = Command::class, name = Command.TYPE),
    ]
)
interface Component {
    var id: String

    @get:JsonIgnore
    val type: String
}

data class Command(
    val value: String,
    val component: Component
) : Component by component {
    override val type: String
        get() = TYPE

    companion object {
        const val TYPE = "command"
    }
}

data class Space(
    val space: String,
    private val component: Component
) : Component by component {
    override val type: String
        get() = TYPE

    companion object {
        const val TYPE = "space"
    }
}

data class Info(
    override var id: String,
    override val type: String = "",
) : Component

class FooTest {
    //    private val objectMapper = ObjectMapperFactory.createObjectMapper(emptyList())
    private val objectMapper = JsonMapper.builder()
        .addModule(KotlinModule())
        .serializationInclusion(JsonInclude.Include.NON_NULL)
        .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
        .enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)
        .enable(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER)
        .build()

    @Test
    fun `should deserialize`() {

        val value = objectMapper.writeValueAsString(
            Command(
                value = "text",
                component = Info(id = "d")
            )
        )

        val obj = objectMapper.readValue(value, Component::class.java)
        assertThat(value).isEqualTo(obj)
    }
}

错误


com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'Info' as a subtype of `<>.<>.<>.<>.jackson.Component`: known type ids = [command, space] (for POJO property 'component')
 at [Source: (String)"{"type":"command","value":"text","component":{"type":"Info","id":"d"},"id":"d"}"; line: 1, column: 54] (through reference chain: <>.<>.<>.<>.jackson.Command["component"])

【问题讨论】:

    标签: json kotlin jackson jackson-databind kotlin-delegate


    【解决方案1】:

    稍微更改了您的代码以修复反序列化,因为它在创建 Info 组件时失败,因为它不在已知的JsonSubTypes 列表中。

    1. 覆盖 Info 类的类型字段
    data class Info(
        override var id: String,
        override val type: String = "info",
    ) : Component
    
    1. 添加到JsonSubTypes注解:
    @JsonSubTypes(
         value = [
             Type(value = Space::class, name = Space.TYPE),
             Type(value = Command::class, name = Command.TYPE),
             Type(value = Info::class, name = "info"),
         ]
     )
     interface Component
    

    测试代码中的小修复:

            val before = Command(
                value = "text",
                component = Info(id = "d")
            )
            val asString = objectMapper.writeValueAsString(before)
    
            val after = objectMapper.readValue(asString, Component::class.java)
            assertThat(after).isEqualTo(before)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多