kotlin:不能用杰克逊解析字符串

时间:2018-03-09 13:32:50

标签: jackson kotlin jackson-modules

我使用lib jackson-module-kotlin将json字符串解析为object。

我的问题是当我将字符串解析为枚举时,当我使用intellij启动时,我有这个堆栈跟踪:

  

引起:kotlin.reflect.jvm.internal.KotlinReflectionInternalError:   对内置Kotlin类型的反思尚未得到完全支持。没有   为公共最终val名称找到的元数据:kotlin.String在中定义   kotlin.Enum [DeserializedPropertyDescriptor @ 212b316a]

当我使用maven启动时,我没有遇到此问题。

我使用kotlin 1.1.51,使用intellij kotlin插件1.2.0-release-IJ2017.3-1,我的目标是JVM 1.8,我使用的是jackson-module-kotlin版本2.8.7

我该怎么办?

 enum class CType { DEAL, FILE }
 data class Code(val code: String, val type: CType)

 fun testDeserialization() {
    val mapper = jacksonObjectMapper()
    // following line throws an exception:
    mapper.readValue("""{"code":"A","type":"DEAL"}""", Code::class.java)
 }

4 个答案:

答案 0 :(得分:0)

Intellij最有可能使用kotlin编译器版本1.2.0(来自插件),它似乎不能正确支持反射。

我建议你做以下其中一项:

  1. 将maven和intellij kotlin插件中的kotlin版本升级到更新版本(例如1.2.30)。如果你这样做,你还必须将jackson-module-kotlin更新为> = 1.9,因为与kotlin 1.2不兼容(见here)。

  2. 在Intellij Idea设置中将kotlin编译器版本设置为1.1。

  3. 在Intellij Idea和maven / gradle中使用相同版本的kotlin通常是个好主意。

答案 1 :(得分:0)

你需要使用与Kotlin 1.2.x兼容的Jackson的Kotlin模块,这至少包括这三个版本的模块:

  • 2.9.4.1 (适用于任何2.9.x的杰克逊,但最好最近使用)
  • 2.8.11.1 (杰克逊2.8.x)
  • 2.7.9.1 (杰克逊2.7.x)

否则,您将遇到库不匹配的问题。

jackson-module-kotlin homepage将这些列为当前版本,但它们可能会更改,您可以检查各种Maven存储库搜索引擎,以查看哪些库版本可用以及它们在Kotlin上具有哪些依赖关系以查找匹配版本

另请注意,您可以导入ObjectMapper类的扩展名并使用已知类型,而不是:

val something = mapper.readValue("""{"code":"A","type":"DEAL"}""", Code::class.java)
你会得到:

val something: Code = mapper.readValue("""{"code":"A","type":"DEAL"}""")

或者:

val something = mapper.readValue<Code>("""{"code":"A","type":"DEAL"}""")

使用已擦除的类型(即Whatever::class.java)通常很糟糕,因为这对于具有泛型类型参数的任何内容都不起作用,并且在反序列化为集合时使用已知类型也可以很好地工作。

答案 2 :(得分:0)

您必须做一些事情。

Jackson 依赖项更新到最新版本(目前为 2.9.4 )。 将 Kotlin 版本更新为等于或大于 1.3.0 的版本。

确保将以下依赖项添加到build.gradle:

implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_version"

...然后您在杰克逊registerKotlinModule()上调用ObjectMapper,您的枚举代码应如下所示:

enum class CType(@get:JsonValue val value: String) {
    DEAL("deal"),
    FILE("file");

    companion object {

        @JsonCreator
        fun fromString(value: String): CType? {
            for (type in CType.values()) {
                if (type.name.equals(value, true)) {
                    return gender
                }
            }
            return null
        }
    }
}

答案 3 :(得分:0)

使它起作用的唯一方法是添加其他package nc.features.algo.model import com.fasterxml.jackson.annotation.JsonCreator import com.fasterxml.jackson.annotation.JsonValue enum class LHStatus ( @get:JsonValue val code: Int ) { LH_POS_OVU_WAITING(1), LH_NEG_OVU_WAITING(2), ; companion object { @JsonCreator @JvmStatic fun deser(code: Int?): LHStatus? { if (code == null) return null for (i in values()) { if (i.code == code) return i } return null } } } 批注。我有aws rds create-db-snapshot \ --db-instance-identifier mydbinstance \ --db-snapshot-identifier mydbsnapshot aws rds restore-db-instance-from-db-snapshot \ --db-instance-identifier mynewdbinstance \ --db-snapshot-identifier mydbsnapshot ,所有内容都无济于事:

{{1}}