提问人:Hasherino 提问时间:10/24/2023 最后编辑:Hasherino 更新时间:10/24/2023 访问量:57
当变量不可为空时,在请求正文中传递 null 时的 NPE
NPE when passing null in request body when variable is not nullable
问:
我有一个带有 REST API 的 Kotlin 应用程序。终结点接受请求正文,该正文被反序列化为以下数据类:POST
data class RequestBody(
val ids: Ids? = null,
)
data class Ids(
val include: List<String>? = null,
val exclude: List<String>? = null
)
使用以下命令调用此终结点时:
{
"ids": {
"include": [
null
]
},
}
尝试使用 kotlinx JSON 序列化器序列化 RequestBody 时,我得到了一个 NPE:
val jsonSerializer = Json { encodeDefaults = true }
fun getData(
ids: Ids
): Output {
val inputJson = jsonSerializer.encodeToJsonElement(
ids = Ids ?: Ids()
)
...
}
错误信息:java.lang.NullPointerException: Parameter specified as non-null is null: method kotlinx.serialization.internal.StringSerializer.serialize
对我来说,问题似乎出在请求正文的反序列化期间,因为,例如,如果我使 not nullable: ,然后尝试使用 调用端点,那么我会得到一个预期的错误: 。
那么,为什么当我在列表中传递 null 时,即使类型被指定为不可为 null,它也不会抛出此错误呢?Ids
val ids: Ids
"ids": null
JSON parse error: Instantiation of [...] value failed for JSON property ids due to missing (therefore NULL) value for creator parameter ids which is a non-nullable type
include
String
编辑:在 Kotlin 文档中,它说 Kotlin 中 NPE 的唯一可能原因是:
- 对 的显式调用。
throw NullPointerException()
- 下面介绍的运算符的用法。
!!
- 初始化方面的数据不一致,例如:
- 构造函数中未初始化的可用被传递并在某处使用(“泄漏”)。
this
this
- 超类构造函数调用一个开放成员,该成员在派生类中的实现使用未初始化的状态。
- 构造函数中未初始化的可用被传递并在某处使用(“泄漏”)。
这看起来不适合其中任何一个?
答:
是的,您正在将值传递到不接受 s 的 List 中。请尝试发布以下内容:null
null
{
"ids": {
"include": null
},
}
或者,更新列表以接受值:null
val include: List<String?>? = null
评论
val include: List<String?>? = null
kotlinx.serialization
Exception in thread "main" kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 9: Expected string literal but 'null' literal was found
正如 Jorn 所说,这很可能是由于使用非 Kotlin 解析器将请求数据反序列化为数据类造成的。用于解决此问题:filterNotNull()
data class RequestBody(
val ids: Ids? = null,
)
data class Ids(
var include: List<String>? = null,
var exclude: List<String>? = null
) {
init {
include = include?.filterNotNull()
exclude = exclude?.filterNotNull()
}
}
编辑:在这里为这个特定问题找到了更好的解决方案
评论
整个列表的
null
值是有区别的HttpMessageNotReadableException: JSON parse error
NullPointerException
List<String>?
null
null