如何使用jackson反序列化Kotlin集合
示例代码我想要的是:
data class D(val a: String, val b: Int) val jsonStr = """[{"a": "value1", "b": 1}, {"a": "value2", "b":"2}]""" // what I need val listOfD: List = jacksonObjectMapper().whatMethodAndParameter?
使用Jackson Kotlin模块当前版本 ,如果您导入完整的模块包或特定的扩展function,您将拥有所有可用的扩展方法。 如:
import com.fasterxml.jackson.module.kotlin.* val JSON = jacksonObjectMapper() // keep around and re-use val myList: List = JSON.readValue("""["a","b","c"]""")
因此,Kotlin的Jackson模块会推断出正确的types,并且不需要TypeReference
实例。
所以你的情况(稍微改名并修复了数据类和JSON):
import com.fasterxml.jackson.module.kotlin.readValue data class MyData(val a: String, val b: Int) val JSON = jacksonObjectMapper() val jsonStr = """[{"a": "value1", "b": 1}, {"a": "value2", "b": 2}]""" val myList: List = JSON.readValue(jsonStr)
你也可以使用下面的forms:
val myList = JSON.readValue>(jsonStr)
没有导入,你会有一个错误,因为没有find扩展function。
TL; DR
用jackson2.6.3-2
做@ jason-minard建议并简单使用:
import com.fasterxml.jackson.module.kotlin.readValue val listOfD: List = jacksonMapper.readValue(jsonStr)
细节
Kotlin和反序列化集合没有什么特别之处,尽管你需要kotlin jackson模块来反序列化没有注解的数据类。
也就是说,为了跟踪列表( D
)的通用参数,在你的情况下将需要完整的通用types信息。 否则(例如,如果你使用readValue(jsonStr, List::class.java)
),Jackson只会将其视为已清除types(即List
)(正如Kotlin明确指出的那样)并将其反序列化为List
不知道它必须构造D
s。 这是通过在Java中使用TypeReference
的匿名子类来TypeReference
,以便Jackson可以在运行时访问完整的通用types以反序列化。
jackson的Java代码从字面上翻译成Kotlin,下面的代码实现了你想要的(和@eski一样,注意到你的例子中的JSON是无效的):
val jacksonMapper = ObjectMapper().registerModule(KotlinModule()) val jsonStr = """[{"a": "value1", "b": 1}, {"a": "value2", "b":2}]""" val listOfD: List = jacksonMapper.readValue(jsonStr, object : TypeReference>(){}) assertEquals(listOf(D("value1", 1), D("value2", 2)), listOfD)
这个有点冗长而且很丑陋,所以你可以把它隐藏在一个Kotlin(扩展)函数中(特别是如果你打算多次使用它的话):
inline fun ObjectMapper.readValue(json: String): T = readValue(json, object : TypeReference(){})
这将允许你然后只是打电话给:
val listOfD: List = jacksonMapper.readValue(jsonStr)
而这正是2.6.3-2
jacksonKotlin模块所包含的2.6.3-2
。