如何使用 micronaut 序列化和注释来序列化具有多态属性的类?

joe*_*oel 5 jackson kotlin micronaut

我按照本指南使用带有 Jackson 注释的 Micronaut 序列化。当我创建一个抽象Base类和一个Derived类时,我可以使用@JsonTypeInfo@JsonSubTypes来正确序列化该类的对象Derived

OtherClass但是,当我序列化具有类型Base但具有运行时类型的属性的对象 时Derived,该属性将序列化为Base

下面的代码应该可以解释我的问题。请注意,我正在使用io.micronaut.serde.ObjectMapper,当我将其替换为它时com.fasterxml.jackson.databind.ObjectMapper,它会按预期工作。

有没有办法让它使用注释来工作?

import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo
import io.kotest.core.spec.style.ShouldSpec
import io.kotest.matchers.string.shouldContain
import io.micronaut.serde.ObjectMapper
import io.micronaut.serde.annotation.Serdeable
import io.micronaut.test.extensions.kotest.annotation.MicronautTest

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "class")
@JsonSubTypes(JsonSubTypes.Type(Derived::class))
@Serdeable
abstract class Base(val baseProperty: String = "baseProperty")

@Serdeable
class Derived : Base()

@Serdeable
class OtherClass(val otherProperty: Base)

@MicronautTest
class SerializeTest(objectMapper: ObjectMapper) : ShouldSpec({
    should("serialize Derived") {
        val derived: Base = Derived()
        val valueAsString = objectMapper.writeValueAsString(derived)

        /**
         * succeeds:
         * valueAsString = "{"class":"com.example.Derived","baseProperty":"baseProperty"}"
         */
        valueAsString shouldContain "class"
    }

    should("serialize otherProperty as Derived") {
        val derived = Derived()
        val otherClass = OtherClass(derived)
        val valueAsString = objectMapper.writeValueAsString(otherClass)

        /**
         * fails:
         * valueAsString = "{"otherProperty":{"baseProperty":"baseProperty"}}"
         * expected: valueAsString = "{"otherProperty":{"class":"com.example.Derived","baseProperty":"baseProperty"}}"
         */
        valueAsString shouldContain "class"
    }
})
Run Code Online (Sandbox Code Playgroud)

And*_*ewL 0

我没有使用 Micronaut 序列化,但使用了经典的 Jackson for Kotlin@JsonTypeInfo@JsonSubTypes这对于顶级对象或嵌入式对象(如OtherClass.

在我的一个用例中,我花了很长时间才发现注释上需要此属性@JsonTypeInfo

visible = true
Run Code Online (Sandbox Code Playgroud)

所以我并不是说这是一个解决方案,但visible属性文档说

默认值为 false,这意味着 Jackson 处理并从传递给 JsonDeserializer 的 JSON 内容中删除类型标识符。

所以也许这是相关的,因此内部对象的类型不会被擦除以便在对象图中更高的位置查看?