Kotlin - 如何在杰克逊 Json 反序列化期间防止 null 进入 Map 对象?



首先,让我通过一些可运行的代码来帮助您解决我想解决的问题:

(如果要运行此示例代码,请包含 Maven 依赖项(

<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>2.9.4.1</version>
</dependency>

只需创建一个 Kotlin 文件,然后通过下面的可运行代码:

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
data class MapObject(val map: Map<String, String>, val age: Int)
data class SimpleObject(val name:String, val age: Int)
data class MapSimpleObject(val map: SimpleObject, val age: Int)
fun main(args: Array<String>) {
val mapper = jacksonObjectMapper()
val mObj: MapObject = mapper.readValue("""{"map": {"name": null}, "age": 1}""")
println(mObj)  // mObj can be created, print "MapObject(map={name=null}, age=1)", which is not nice
val msObj: MapSimpleObject = mapper.readValue("""{"map": {"name": null, "age": 1}, "age": 1}""")
println(msObj)  // throw MissingKotlinParameterException at line above, which is nice
val sObj: SimpleObject = mapper.readValue("""{"name": null, "age": 1}""")
println(sObj)  // throw MissingKotlinParameterException at line above, which is nice
// val m: Map<String, Int> = mapOf(null to 2)  // won't compile, which is nice
}

如您所见,特别是对于val mObj: MapObject,即使MapObjectmap是在 Kotlin 中定义的具有非空类型的 Map,仍然可以使用 Json 有效负载(如{"map": {"name": null}, "age": 1}(创建对象,从而mObj对象MapObject(map={name=null}, age=1)

这不是我想要的,我希望 Kotlin 的空安全功能能够捕获这一点,如果我像这样放置 json 有效负载,我会抛出一些异常。

那么,如果我有像data class MapObject(val map: Map<String, String>, val age: Int)这样的数据类结构,如何确保没有注入null呢?

IIUC,Kotlin 的空安全主要是编译时。没有什么可以阻止null在运行时通过反射设置为不可为空的属性,正如 Kotlin 参考所述:

。NPE的唯一可能原因可能是:

Java 互操作:... 用于 Java 互操作的泛型类型具有不正确的可空性,例如一段 Java 代码可能会将 null 添加到 Kotlin MutableList 中,这意味着应该使用 MutableList 来处理它;

最新更新