我遇到了意外错误,不确定如何处理。
我有一个像这样的数据类:
data class Payload (
@SerializedName("id")
var id: String
@SerializedName("type")
var type: String,
@SerializedName("data")
var data: String
)
还有一个像这样的简单Spring控制器:
@PostMapping("/some-endpoint")
fun dataHandler(@RequestBody payload: Payload): String{
when (payload.type){
"someType" -> {
val result = try {
gson.fromJson(payload.data, payloadData::class.java)
} catch (e: Exception){
throw BadDataException("Bad Data")
}
payloadProcessor.process(result, payload.id) // NPE here
}
"otherType" -> {
doSomethingElseHere()
}
}
}
当执行到达payloadProcessor.process时,将出现空指针异常,因为id
显然为空。另一方面,对象已创建,并且剩余的两个值似乎已正确填充。
如果添加检查空值的if语句,则ide会抱怨有效载荷属性永远不会为空,从而将if语句标记为冗余,但实际上并非如此。
我的印象是null安全属性是...好吧... null安全。至少我希望一旦对象被构造后,空指针异常就会发生。
我的问题是:
答案 0 :(得分:1)
问题出在Gson,而不是Spring。 Gson是为与Java一起使用而设计的,它在可空类型和不可空类型之间没有任何区别,因此无论如何,Gson都会很高兴地分配空值。
不幸的是,这里没有神奇的解决方案。您可以编写自己的TypeAdapter,在构造数据类之前显式检查null值,但是如果您有很多类,那将变得非常重复。另外,您可以创建自己的TypeAdapterFactory并使用Kotlin的反射库来检查哪些类型可以为空,哪些不能为空,但这会对性能和依赖性产生各种影响。
*有可空性注释(@ Nonnull,@ Nullable),但是Gson不会对其进行检查。