当前位置:  开发笔记 > 前端 > 正文

如何使用Kotlin + Jackson将JSON反序列化为List <SomeType>

如何解决《如何使用Kotlin+Jackson将JSON反序列化为List<SomeType>》经验,为你挑选了3个好方法。

反序列化以下JSON的正确语法是什么:

[ {
  "id" : "1",
  "name" : "Blues"
}, {
  "id" : "0",
  "name" : "Rock"
} ]

我试过了:

//Works OK
val dtos  = mapper.readValue(json, List::class.java)

不过我想:

val dtos : List  = mapper.readValue(json, 
    List::class.java)

上面的语法不正确,并给出: only classes are allowed on the left hand side of a class literal



1> Jayson Minar..:

注意: @IRus的答案也是正确的,它在我写这篇文章的同时被修改以填写更多细节.

您应该使用Jackson + Kotlin模块,否则当您没有默认构造函数时,您将有其他问题反序列化为Kotlin对象.

您的第一个代码示例:

val dtos  = mapper.readValue(json, List::class.java)

返回一个推断类型,List<*>因为你没有指定更多的类型信息,它实际上是一个List>不是真的"工作正常",但没有产生任何错误.这是不安全的,不是打字的.

第二个代码应该是:

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue

val mapper = jacksonObjectMapper()
// ...
val genres: List = mapper.readValue(json)

你不需要在任务的右侧做任何其他事情,杰克逊的Kotlin模块将重新设计仿制品并在TypeReference内部创建杰克逊.注意readValue导入,您需要或.*com.fasterxml.jackson.module.kotlin包的扩展功能是做所有的魔力.

一个稍微不同的替代方案也有效:

val genres = mapper.readValue>(json)

没有理由不使用Jackson的扩展功能和附加模块.它很小并且解决了其他需要你跳过箍来制作默认构造函数或者使用一堆注释的问题.使用该模块,您的类可以是普通的Kotlin(可选为data类):

class GenreDTO(val id: Int, val name: String)



2> miensol..:

你得到的错误是关于以下表达式:

List::class.java

由于jvm如何处理泛型,List因此编译器抱怨没有单独的类.同样在Java中,以下内容不会编译:

List.getClass()

这是一个将正确反序列化列表的示例:

val value:List = mapper.readValue(json, object : TypeReference>() {})

正如@JaysonMinard指出的那样,你可以使用jackson-module-kotlin来简化调用:

val genres: List = mapper.readValue(json)
// or
val genres = mapper.readValue>(json)

这是可能的,因为reified type parameters.考虑查看Extensions详细信息.



3> Ruslan..:

以下代码适合我:

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import com.fasterxml.jackson.module.kotlin.registerKotlinModule



val json = """[ {
  "id" : "1",
  "name" : "Blues"
}, {
  "id" : "0",
  "name" : "Rock"
} ]"""

data class GenreDTO(val id: Int, val name: String)

val mapper = ObjectMapper().registerKotlinModule()

fun main(args: Array) {
    val obj: List = mapper.readValue(json)
    obj.forEach {
        println(it)
    }
}

因为杰克逊-科特林模块(即使用内定义的扩展功能的这一工作物化泛型):

 public inline fun  ObjectMapper.readValue(content: String): T = readValue(content, object: TypeReference() {})

谢谢@JaysonMinard通知我.

输出:

GenreDTO(id=1, name=Blues)
GenreDTO(id=0, name=Rock)

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有