如何在 Retrofit 中使用 Kotlin 枚举?

问题描述 投票:0回答:4

如何使用枚举解析 JSON 来建模?

这是我的枚举类:

enum class VehicleEnumEntity(val value: String) {
   CAR("vehicle"),
   MOTORCYCLE("motorcycle"),
   VAN("van"),
   MOTORHOME("motorhome"),
   OTHER("other")
}

我需要将

type
解析为枚举

“车辆”:{ “数据”: { “类型”:“车辆”, “id”:“F9dubDYLYN” } }

编辑

我尝试过标准方法,只需将我的枚举传递给 POJO,它总是为空

android enums gson kotlin retrofit2
4个回答
94
投票
enum class VehicleEnumEntity(val value: String) {
   @SerializedName("vehicle")
   CAR("vehicle"),

   @SerializedName("motorcycle")
   MOTORCYCLE("motorcycle"),

   @SerializedName("van")
   VAN("van"),

   @SerializedName("motorhome")
   MOTORHOME("motorhome"),

   @SerializedName("other")
   OTHER("other")
}

来源


16
投票

另一个选项:使用自定义(反)序列化器,该序列化器使用枚举的

value
,而不是
name
(默认)。这意味着您不需要注释每个枚举值,而是可以注释枚举类(或将适配器添加到
GsonBuilder
)。

interface HasValue {
    val value: String
}

@JsonAdapter(EnumByValueAdapter::class)
enum class VehicleEnumEntity(override val value: String): HasValue {
   CAR("vehicle"),
   MOTORCYCLE("motorcycle"),
   VAN("van"),
   MOTORHOME("motorhome"),
   OTHER("other")
}

class EnumByValueAdapter<T> : JsonDeserializer<T>, JsonSerializer<T>
    where T : Enum<T>, T : HasValue {
    private var values: Map<String, T>? = null

    override fun deserialize(
        json: JsonElement, type: Type, context: JsonDeserializationContext
    ): T? =
        (values ?: @Suppress("UNCHECKED_CAST") (type as Class<T>).enumConstants
            .associateBy { it.value }.also { values = it })[json.asString]

    override fun serialize(
        src: T, type: Type, context: JsonSerializationContext
    ): JsonElement = JsonPrimitive(src.value)
}

相同的适配器类可以在其他枚举类上重用。


3
投票

例如,如果后端服务响应整数。您可以将构造函数参数更改为

Int

enum class Day(val rawValue: Int) {
    @SerializedName("1")
    SUNDAY(1),
    @SerializedName("2")
    MONDAY(2),
    @SerializedName("3")
    TUESDAY(3),
    @SerializedName("4")
    WEDNESDAY(4),
    @SerializedName("5")
    THURSDAY(5),
    @SerializedName("6")
    FRIDAY(6),
    @SerializedName("7")
    SATURDAY(7),
    @SerializedName("-1")
    UNSUPPORTED(-1);

    companion object {
        fun from(findValue: Int): Day = values().firstOrNull { it.rawValue == findValue } ?: UNSUPPORTED
    }
}

Nitpick:

from
函数可以帮助您通过给定的
Int
轻松找到枚举值。


0
投票

如果您使用

kotlinx.serialization
,那么您只需将枚举类标记为
@Serializable
并使用
@SerialName
及其值:

@Serializable
enum class VehicleEnumEntity(val value: String) {
   @SerialName("vehicle")
   CAR("vehicle"),

   @SerialName("motorcycle")
   MOTORCYCLE("motorcycle"),

   @SerialName("van")
   VAN("van"),

   @SerialName("motorhome")
   MOTORHOME("motorhome"),

   @SerialName("other")
   OTHER("other")
}
© www.soinside.com 2019 - 2024. All rights reserved.