FasterXML / FasterXML/jackson-module-kotlin

Polymorphic sealed class missing type information

Offen
#765 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
question
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.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.