且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何将 JSON 反序列化为 List与 Kotlin + Jackson

更新时间:2023-01-16 15:16:47

注意: @IRus 的回答也是正确的,正在修改同时我写这个来填写更多细节.

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

You should use the Jackson + Kotlin module or you will have other problems deserializing into Kotlin objects when you do no have a default constructor.

您的第一个代码示例:

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

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

Is returning an inferred type of List<*> since you did not specify more type information, and it is actually a List<Map<String,Any>> which is not really "working OK" but is not producing any errors. It is unsafe, not typed.

第二个代码应该是:

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

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

您在作业的右侧不需要任何其他内容,Jackson 的 Kotlin 模块将具体化泛型并在内部为 Jackson 创建 TypeReference.请注意 readValue 导入,您需要该导入或 .*com.fasterxml.jackson.module.kotlin 包具有扩展功能做所有的魔法.

You do not need anything else on the right side of the assignment, the Kotlin module for Jackson will reify the generics and create the TypeReference for Jackson internally. Notice the readValue import, you need that or .* for the com.fasterxml.jackson.module.kotlin package to have the extension functions that do all of the magic.

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

A slightly different alternative that also works:

val genres = mapper.readValue<List<GenreDTO>>(json)

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

There is no reason to NOT use the extension functions and the add-on module for Jackson. It is small and solves other issues that would require you to jump through hoops to make a default constructor, or use a bunch of annotations. With the module, your class can be normal Kotlin (optional to be data class):

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