【问题标题】:How to get Jackson JsonProperty of enum values in Kotlin?如何在 Kotlin 中获取枚举值的 Jackson JsonProperty?
【发布时间】:2022-08-19 01:45:37
【问题描述】:

我正在构建一个模式生成器,并且我正在尝试获取枚举值的JsonProperty,例如,对于此类:

enum class Size {
    @JsonProperty(\"really-tall\") TALL,
    @JsonProperty(\"really-grande\") GRANDE;
}

我想得到名单\"really-tall\", \"really-grande\"

如何访问枚举的注释? 谢谢!

更新:

基于此reply 的通用KType 的解决方案:

return (jvmErasure.java as Class<Enum<*>>)
  .enumConstants
  .map {
    it.javaClass.getField(it.name).getAnnotation(JsonProperty::class.java)?.value // Get the JsonProperty string first if exists
      ?: it.name
  }

标签: kotlin enums jackson annotations


【解决方案1】:

更新:来自 OP 的附加问题

如何使第一种方法适用于通用 KType

inline fun <reified T : Enum<T>> getJsonPropertyAnnotations() = enumValues<T>().map {
    it.declaringClass
        .getField(it.name)
        .getAnnotation(JsonProperty::class.java)
        .value
}

class SomeTest : StringSpec({
    "getJsonPropertyAnnotations" {
        getJsonPropertyAnnotations<Size>() 
            shouldBe listOf("really-tall", "really-grande")
    }
})

请注意,在 Kotlin 1.7 中,IntelliJ 可能会显示弃用警告,并在 getJsonPropertyAnnotations 中错误地替换 declaringClass。我想这将在以后的版本中得到解决。 Link to related source


下面的代码应该做你想做的事。

class SomeTest : StringSpec({
    "getting annotation values" {
        val result = enumValues<Size>().map {
            it.declaringClass.getField(it.name).getAnnotation(JsonProperty::class.java).value
        }
        result shouldBe listOf("really-tall", "really-grande")
    }
})

另一种选择(更少的代码):在枚举类中添加一个 String 属性(我在下面的代码中将其称为 someFieldName),使用 @get:JsonValue 进行注释,并使用所需的字符串值构造每个枚举条目。 @get:JsonValue 在序列化过程中将使用 someFieldName 而不是枚举值。

enum class Size(@get:JsonValue val someFieldName: String) {
    TALL("really-tall"),
    GRANDE("really-grande");
}

再次进行相同的测试

class SomeTest : StringSpec({
    "getting prop values" {
        val result = enumValues<Size>().map {
            it.someFieldName
        }
        result shouldBe listOf("really-tall", "really-grande")
    }
})

我们在一个正在进行的项目中使用后一种方法。

【讨论】:

  • 谢谢!如何使第一种方法适用于通用 KType
【解决方案2】:

这是 ObjectMapper 上的一个扩展函数,用于询问映射器如何序列化枚举的值。这比仅检查 @JsonProperrty 注释更加健壮,因为它可以与 @JsonValue 以及在映射器中注册的任何自定义注释内省器一起使用。

inline fun <reified T : Enum<T>> ObjectMapper.enumValues() : List<String> {
    return convertValue(
        kotlin.enumValues<T>(),
        jacksonTypeRef<List<String>>()
    )
}

用法:

println(jsonMapper().enumValues<Size>())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多