首页 > 解决方案 > 在 Kotlin 中如何处理具有内部属性类型的多态?

问题描述

美好的一天,弗里曼先生!我正在尝试为外部 api 的 Json / Object 转换制作一个非平凡的多态 dto。dto 包含属性,可以有两种类型,但这取决于它的内部值......假设我有一个这样的 json:

[{
    "Id": 1,
    "Age": 2,
    "Car": {
        "MaxPassengers": 20,
        "Model": "Audi",
        "UniqueAudyTechnology": true
    },
    "Vendor": "VOLKSWAGEN AUTO GROUP (VAG)"
},
{
    "Id": 2,
    "Age": 1,
    "Car": {
        "MaxPassengers": 5,
        "Model": "Skoda",
        "SkodaRentalProgramId": 100
    },
    "Vendor": "VOLKSWAGEN AUTO GROUP (VAG)"
}]

所以,在“汽车”字段中,我可以有任何汽车类,但要定义它,我需要使用 Car.Model 属性。我做了一个通用的接口和数据类:

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.EXISTING_PROPERTY,
    property = "Model",
    visible = true
)
@JsonSubTypes(value = [
    JsonSubTypes.Type(value = Audi::class, name = "Audi"),
    JsonSubTypes.Type(value = Skoda::class, name = "Skoda")
])
@ApiModel(description = "Used car")
interface UsedCar {
    @get:JsonProperty("Id")
    val id: Long

    @get:JsonProperty("Age")
    val age: Int

    @get:JsonProperty("Vendor")
    val vendor: String
}

和数据类:

data class Audi(

    @JsonProperty("UniqueAudyTechnology")
    val hasUniqueAudyTechnology: boolean,

    @JsonProperty("Model")
    val model: String,

    @JsonProperty("MaxPassengers")
    val maxPassengers: Int
)

data class Skoda(

    @JsonProperty("SkodaRentalProgramId")
    val skodaRentalProgramId: Int,

    @JsonProperty("Model")
    val model: String,

    @JsonProperty("MaxPassengers")
    val maxPassengers: Int
)

事实上,我想让杰克逊通过子类型属性模型解析子类型。我整天都在尝试,但我无法理解我错过了什么......?PS代码可能不起作用,因为我已经删除了奥迪和斯柯达对二手车的实现......对不起......不知道如何处理它......

标签: jsonkotlinjackson

解决方案


恕我直言,对于发送多个未使用字段的 API,这是最简单的解决方案。

@JsonIgnoreProperties(ignoreUnknown = true)
data class Car(
        @JsonProperty("Id")
        val id: Long,

        @JsonProperty("Age")
        val age: Int,

        @JsonProperty("Vendor")
        val vendor: String,

        @JsonProperty("UniqueAudiTechnology")
        val hasUniqueAudiTechnology: Boolean,

        @JsonProperty("SkodaRentalProgramId")
        val skodaRentalProgramId: Int,

        @JsonProperty("Model")
        val model: String,

        @JsonProperty("MaxPassengers")
        val maxPassengers: Int)

如果有很多字段,它会变得非常乏味,但首先这是一个糟糕的 API 设计。

以上述方式检查此答案以获取更多信息。


推荐阅读