【问题标题】:how to avoid getting an extra field with random information when using jackson Subtypes?使用杰克逊子类型时如何避免获得带有随机信息的额外字段?
【发布时间】:2020-02-08 13:22:11
【问题描述】:

我正在尝试使用 JSON 子类型为不同的事件创建某种“通用”对象接收者。

目前我有这样的事情:

 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "color")
    @JsonSubTypes(
            JsonSubTypes.Type(value = Color::class, name = "RED"),
            JsonSubTypes.Type(value = Color::class, name = "YELLOW"),
            JsonSubTypes.Type(value = SpecialColor::class, name = "SPECIAL_1"),
            JsonSubTypes.Type(value = SpecialColor::class, name = "SPECIAL_2"),
            JsonSubTypes.Type(value = CustomColor::class, name = "CUSTOM")
        )


    interface EventColor{
        val eventId: String
        val color: ColorType
    }

    enum class ColorType {
        RED, YELLOW
    }

然后我有我的对象

data class Color(
    @get:JsonProperty override val eventId: String,
    @get:JsonProperty override val color: ColorType
): EventColor

当我做一个新的 Color 实例时问题就来了

Color("123", ColorType.RED)

当我打印对象时,我得到了正确的信息

Color(eventId=event123, ColorType.RED)

但是当我这样做时

private val mapper = jacksonObjectMapper()
val mapped = mapper.writeValueAsString(myObject)

打印我的对象我得到了这个

{"color":"RED","eventId":"event123","color":"YELLOW"}

这是我的映射器的导入

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper

我不知道发生了什么,也不知道这怎么可能,知道我做错了什么吗?

【问题讨论】:

    标签: json kotlin jackson


    【解决方案1】:

    这两个注释@JsonSubTypes.Type 具有相同的类没有意义。我预计会出现错误,但显然他们没有测试这种情况,第一个只是被忽略了。因此,您的注释说“在序列化EventColor 时,如果它是Color,则添加"color":"YELLOW"”(反序列化EventColor 时,如果它有"color":"YELLOW",则将其设为Color)。

    如果Color真的是EventColor的唯一实现,我相信正确的注解是

    @JsonTypeInfo(use = JsonTypeInfo.Id.NONE, defaultImpl = Color::class)
    interface EventColor{
        val eventId: String
        val color: ColorType
    }
    

    或者直接去掉接口直接使用Color

    【讨论】:

    • 感谢@Alexey 的回复,不幸的是,Color 不是 EventColor 的唯一实现,因为还有其他几个,一些 ColorType 共享相同的类,因为它们很简单,但其他更复杂并且有自己的属性。你认为它仍然可以这样工作吗?
    • 再一次,在您的编辑中,您仍然有 Color 的 2 个子类型注释和 SpecialColor 的 2 个子类型注释。这是行不通的。您希望 ColorSpecialColor 的 JSON 看起来如何? SpecialColor 本身长什么样子?
    • 如果你想表达类似“如果colorREDYELLOW,使用Color,如果是SPECIAL_1SPECIAL_2 ,使用SpecialColor 等。”那么我认为没有任何内置支持,您需要编写自己的TypeResolverBuilder 并使用@JsonTypeResolver 注释。
    • (注意:通常您区分的属性不是对象本身的一部分,您可以使用"type":"simple"/"special"/"custom" 来决定使用哪个类)
    • Red 或 Yellow 的类应该看起来相同,但里面只有不同的信息。我刚刚再次检查,似乎这个答案仍然有效stackoverflow.com/questions/18394819/…
    猜你喜欢
    • 1970-01-01
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多