当前位置: 首页 > 知识库问答 >
问题:

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

哈骞仕
2023-03-14

我按照本指南将Micronaut Serialization与Jackson注释一起使用。当我创建一个抽象类和一个派生类时,我可以使用@JsonTypeInfo@JsonSubTypes来正确序列化派生类的对象。

但是,当我使用Base class类型的属性序列化Base的对象但使用运行时类型Drive时,该属性被序列化为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"
    }
})

共有1个答案

田化
2023-03-14

我没有使用过Micronaut序列化,但是使用了classical Jackson for Kotlin和< code>@JsonTypeInfo和< code>@JsonSubTypes,这对于top对象或嵌入式对象很适用,就像您在< code>OtherClass中使用的那样。

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

visible = true

因此,我并不声称这是一个解决方案,但是< code>visible属性文档说

缺省值为假,这意味着Jackson处理并从传递给JsonDes身旁化器的JSON内容中删除类型标识符。

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

 类似资料:
  • 问题内容: 我有多态类型,并且可以从JSON反序列化为POJO。实际上,我遵循这里的文档。将POJO序列化为JSON时,我得到了不需要的属性,特别是逻辑类型名称。 当Jackson序列化为JSON时,它提供了我不想公开的类型信息。 我可以以某种方式防止这种情况吗?反序列化时我只想忽略。 问题答案: 一个简单的解决方案是将和配置移至,然后仅注册进行反序列化。

  • 问题内容: 我想在使用Jackson时定义我的自定义序列化策略(要包括的字段)。我知道,我可以使用视图/过滤器来做到这一点,但是它引入了非常不好的一件事- 使用字段名称的字符串表示形式,这会自动导致自动重构出现问题。 如何迫使Jackson序列化仅带注释的属性,仅此而已? 问题答案: 如果禁用所有自动检测,则应仅序列化已注释的属性-无论是属性本身还是吸气剂。这是一个简单的例子:

  • 下面是输出: 我的分级文件中的版本号:

  • 我们希望序列化Java类的模式,以便任何字段或类上存在的所有注释也序列化到模式中。 我没有找到这样做的工具。 Avro不处理非字符串映射键,FasterXML不处理循环引用。它们都不会将注释序列化到模式中。 是否有任何Java JSON(反)序列化程序可以做到这一点?

  • 我的JSON字符串是: 我想要实现的是,当JSON中没有提供schemaVersion时,能够在默认情况下反序列化到SubClassV1,但即使在Superclass中将schemaVersion初始化为“1.0”时,我仍然会收到以下错误: