Another option: use a custom (de)serializer that uses the value
of the enum, instead of the name
(default). This means you don't need to annotate every enum value, but instead you can annotate the enum class (or add the adapter to 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)
}
The same adapter class is reusable on other enum classes.