FasterXML / FasterXML/jackson-module-kotlin
Polymorphic sealed class missing type information
- Vorherrschende Sprache
- Kotlin
- Sterne
- 1.2k
- Forks
- 187
- Ø Merge
- 9 Std. 48 Min.
- Gemergte PRs (30 T.)
- 16
Beschreibung
### Your question
Hi,
maybe I'm missing some important piece or my thinking is a bit too naïve, but I try to write a generic message passing library based on a json protocol.
```kotlin
package com.fasterxml.jackson.module.kotlin.test.github
import com.fasterxml.jackson.annotation.JsonTypeInfo
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.exc.MismatchedInputException
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import junit.framework.TestCase.assertEquals
import org.junit.Assert.assertThrows
import kotlin.test.Test
class ReproductionTest {
@JsonTypeInfo(use = JsonTypeInfo.Id.SIMPLE_NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
sealed class Response{
data class Success(val response: B) : Response()
data class Failure(val error: Err) : Response()
}
@JsonTypeInfo(use = JsonTypeInfo.Id.SIMPLE_NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
sealed class Message {
data class Text(val text: String) : Message()
data class Image(val url: String) : Message()
}
@JsonTypeInfo(use = JsonTypeInfo.Id.SIMPLE_NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type")
sealed class Error {
data class NotFound(val message: String) : Error()
data class BadRequest(val message: String) : Error()
}
val asJson = """{"@type":"Success","response":{"@type":"Text","text":"foo"}}"""
val responseSuccess: Response = Response.Success(Message.Text("foo"))
@Test
fun testReadAsValue() {
val mapper = jacksonObjectMapper()
val refType = mapper.typeFactory.constructParametricType(Response::class.java, Error::class.java, Message::class.java)
// Failing com.fasterxml.jackson.databind.exc.InvalidTypeIdException:
// Could not resolve type id 'Success' as a subtype of ...
assertEquals(
responseSuccess,
mapper.readValue>(asJson, refType)
)
}
@Test
fun testWriteAsValue() {
val mapper = jacksonObjectMapper()
// Failing
assertEquals(
asJson,
mapper.writeValueAsString(responseSuccess) // actual: {"@type":"Success","response":{"text":"foo"}}
)
}
}
```
My expectations/goals would be:
1. if defined at the root type of Err/B type information should be included in the `"response": {...}` value and should be in control of the consuming code side (`Message` & `Error` would be defined there). But the type information is missing the the serialized value
2. and of course it should be deserializable
Is that possible to achieve? I tried various variations, including `mapper.writerFor(refType)`, without any success.
Help is appreciated!
Greetings
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Bewertung
Dieses Issue wurde noch nicht bewertet.