如何使用枚举解析 JSON 来建模?
这是我的枚举类:
enum class VehicleEnumEntity(val value: String) {
CAR("vehicle"),
MOTORCYCLE("motorcycle"),
VAN("van"),
MOTORHOME("motorhome"),
OTHER("other")
}
我需要将
type
解析为枚举
“车辆”:{ “数据”: { “类型”:“车辆”, “id”:“F9dubDYLYN” } }
编辑
我尝试过标准方法,只需将我的枚举传递给 POJO,它总是为空
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")
}
另一个选项:使用自定义(反)序列化器,该序列化器使用枚举的
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)
}
相同的适配器类可以在其他枚举类上重用。
例如,如果后端服务响应整数。您可以将构造函数参数更改为
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
轻松找到枚举值。
如果您使用
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")
}