You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Your question
I have checked issues and docs and could not find solution.
The follwing code properly serialize object (Component) to string, but deserialization from string back to insgtances of Component doesn't work.
Any suggestions how to do it, without removing delegations?
Thanks :)
importcom.fasterxml.jackson.annotation.JsonIgnoreimportcom.fasterxml.jackson.annotation.JsonIncludeimportcom.fasterxml.jackson.annotation.JsonSubTypesimportcom.fasterxml.jackson.annotation.JsonSubTypes.Typeimportcom.fasterxml.jackson.annotation.JsonTypeInfoimportcom.fasterxml.jackson.core.json.JsonReadFeatureimportcom.fasterxml.jackson.databind.DeserializationFeatureimportcom.fasterxml.jackson.databind.json.JsonMapperimportcom.fasterxml.jackson.module.kotlin.KotlinModuleimportorg.assertj.core.api.Assertions.assertThatimportorg.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),
]
)
interfaceComponent {
var id:String
@get:JsonIgnore
val type:String
}
data classCommand(
valvalue:String,
valcomponent:Component
) : Component by component {
overrideval type:String
get() =TYPEcompanionobject {
constvalTYPE="command"
}
}
data classSpace(
valspace:String,
privatevalcomponent:Component
) : Component by component {
overrideval type:String
get() =TYPEcompanionobject {
constvalTYPE="space"
}
}
data classInfo(
overridevarid:String,
overridevaltype:String = "",
) : Component
classFooTest {
// private val objectMapper = ObjectMapperFactory.createObjectMapper(emptyList())privateval 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)
}
}
Error
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"])
The text was updated successfully, but these errors were encountered:
I don't this has anything to do with delegation, but please let me know if I've misunderstood.
The Info class doesn't have an entry in the @JsonSubTypes list, so Jackson doesn't know what it is. Here is a simplified version of your example that works, mainly by adding that entry for Info:
importcom.fasterxml.jackson.annotation.JsonIgnoreimportcom.fasterxml.jackson.annotation.JsonSubTypesimportcom.fasterxml.jackson.annotation.JsonSubTypes.Typeimportcom.fasterxml.jackson.annotation.JsonTypeInfoimportcom.fasterxml.jackson.annotation.JsonTypeInfo.Asimportcom.fasterxml.jackson.annotation.JsonTypeInfo.Idimportcom.fasterxml.jackson.module.kotlin.jsonMapperimportcom.fasterxml.jackson.module.kotlin.kotlinModuleimportorg.junit.Assert.assertEqualsimportorg.junit.Test
@JsonTypeInfo(
use =Id.NAME,
include =As.PROPERTY,
property ="typeInfo"
)
@JsonSubTypes(
value = [
Type(value =Command::class, name =Command.TYPE),
Type(value =Info::class, name ="info")
]
)
interfaceComponent {
var id:String
@get:JsonIgnore
val type:String
}
data classCommand(
valvalue:String,
valcomponent:Component
) : Component by component {
overrideval type:String
get() =TYPEcompanionobject {
constvalTYPE="command"
}
}
data classInfo(
overridevarid:String,
overridevaltype:String = "",
) : Component
classFooTest {
privateval objectMapper = jsonMapper { addModule(kotlinModule()) }
@Test
fun`should deserialize`() {
val expected =Command(value ="text", component =Info(id ="d"))
val value = objectMapper.writerWithDefaultPrettyPrinter()
.writeValueAsString( expected )
println(value)
assertEquals(expected, objectMapper.readValue(value, Component::class.java))
}
}
Note that Jackson can also attempt to determine the type to deserialize into based upon the fields present using deduction.
Your question
I have checked issues and docs and could not find solution.
The follwing code properly serialize object (
Component
) to string, but deserialization from string back to insgtances ofComponent
doesn't work.Any suggestions how to do it, without removing delegations?
Thanks :)
Error
The text was updated successfully, but these errors were encountered: