json - 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
甚至MapObject
'smap
是在 Kotlin 中定义的具有非 Null 类型的 Map,仍然可以使用 Json 有效负载创建对象,例如{"map": {"name": null}, "age": 1}
,生成mObj
的对象为MapObject(map={name=null}, age=1)
这不是我想要的,我希望 Kotlin 的 null 安全功能能够捕捉到这一点,如果我像这样放置 json 有效负载,我会抛出一些异常。
那么,如果我有类似的数据类结构,如何确保null
不注入data class MapObject(val map: Map<String, String>, val age: Int)
?
解决方案
IIUC,Kotlin 的空安全性主要是编译时。正如Kotlin 参考所述,没有什么可以阻止null
在运行时通过反射将其设置为不可为空的属性:
... NPE 的唯一可能原因可能是:
Java 互操作: ... 用于 Java 互操作的通用类型,具有不正确的可空性,例如,一段 Java 代码可能会将 null 添加到 Kotlin MutableList 中,这意味着应该使用 MutableList 来处理它;
推荐阅读
- python - TCP服务器在Python中没有正确接收数据
- sqlite - 如何在 golang 中跟踪对 sqlite3 的更改?
- javascript - 解绑后提交表单
- bash - 如何在 Visual Studio 2019 中使用 git bash 终端配置文件?
- java - 存根方法的 Mockito 单元测试抛出 NullPointerException
- c++ - 在 C++ 模板中发送字符串文字作为参数 - 参数包
- swift - 将 ViewController 添加到 UICollectionviewcell
- javascript - 删除元素后更新行条带化
- oracle - 使用假脱机将表数据导出到 csv 的 Oracle 命令行在数据中包含双引号 (") 时出现问题
- java - 带有嵌套对象的 Java8 流