Jackson Serializaiton/Deserialization 自定义 属性 在枚举中

Jackson Serializaiton/Deserialization by custom property in enum

我想让 Jackson 使用枚举而不是按名称而不是按序号,而是使用我添加的自定义 属性 称为“stringId”。 我想通过系统中的所有枚举来支持这一点,所以我创建了一个名为 StringIdEnum 的接口,FooEnum 将实现该接口。

我正在使用 Kotlin,所以我在名为 stringId 的界面中创建了一个 属性,我在每个枚举值中覆盖了它。

现在我想使用这个 stringId 字段让 Jackson 序列化和反序列化,据我所知,我有几个选择:

  1. 在每个枚举值上使用 @JsonProperty 注释并确保它与 stringId 属性 对齐。 我看到这种方法有两个问题。一个是要添加很多注释(我们在整个系统中有很多枚举 classes)。二 我需要确保注释值和 属性 值应始终相同,这可能会在将来导致问题。
  2. 我尝试使用 READ_ENUMS_USING_TO_STRING 功能,但因为我使用的是接口,所以我无法覆盖接口中的 toString class(我可以在每个枚举中覆盖它 class 但这又像是很多冗余代码)
  3. 实施自定义 serializer/deserializer。 序列化器非常简单,但是,我在反序列化器方面遇到了麻烦。 我想在 StringIdEnum 接口上注册反序列化器,但是我在获取实际 FooType 枚举的所有运行时枚举值时遇到了问题。

StringIdEnum:

interface StringIdEnum {

  val stringId: String
}
enum class FooType(override val stringId: String) : StringIdEnum {
   FOO("FOO"),
   GOO("GOO");
}

设法让它工作:

@JsonSerialize(using = StringIdEnumSerializer::class)
@JsonDeserialize(using = StringIdEnumDeserializer::class)
interface StringIdEnum: DbEnum {

  val stringId: String

}
class StringIdEnumSerializer: StdSerializer<StringIdEnum>(StringIdEnum::class.java) {

  override fun serialize(value: StringIdEnum, gen: JsonGenerator, provider: SerializerProvider) {
    gen.writeString(value.stringId)
  }

}
class StringIdEnumDeserializer : JsonDeserializer<Enum<*>>(), ContextualDeserializer {

  private lateinit var type: JavaType

  override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Enum<*> {
    val t = p.text
    val enumConstants = (type.rawClass as Class<Enum<*>>).enumConstants
    return enumConstants.single { (it as StringIdEnum).stringId == t }
  }

  override fun createContextual(ctxt: DeserializationContext?, property: BeanProperty?): JsonDeserializer<*> {
    val wrapperType: JavaType = property!!.type
    val stringIdEnumDeserializer = StringIdEnumDeserializer()
    stringIdEnumDeserializer.type = wrapperType
    return stringIdEnumDeserializer
  }
}