【发布时间】:2018-06-01 12:52:16
【问题描述】:
首先让我通过一些可运行的代码来帮助您解决我想要解决的问题:
(如果您想运行此示例代码,需要包含 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 的map 是在Kotlin 中定义的具有非Null 类型的Map,仍然可以使用Json 有效负载创建对象,例如{"map": {"name": null}, "age": 1},结果mObj 对象为MapObject(map={name=null}, age=1)
这不是我想要的,我希望 Kotlin 的 null 安全功能能够捕捉到这一点,如果我这样放置 json 有效负载,我会抛出一些异常。
如果我有像data class MapObject(val map: Map<String, String>, val age: Int) 这样的数据类结构,如何确保null 没有被注入?
【问题讨论】:
-
酷,经过大量搜索后,我找不到任何避免这种行为的可能性。
@JsonSetter(contentNulls = Nulls.FAIL, nulls = Nulls.FAIL)必须在 null 上启用失败(如果我理解正确的话),但事实并非如此。所以我看到了两种可能的解决方案:1)使用空值反序列化并在过滤后 2)编写自定义反序列化 -
我将建议与 kurt 提到的类似的东西:创建一个扩展函数来检查读取值之前的空值。这是唯一的想法,正如@jingx 所提到的,没有办法通过反射来避免空值。
标签: json kotlin jackson non-nullable