这是数据类:
data class CreateCommentRequest(
@field:NotNull
@field:NotEmpty
val comment: String,
@field:NotNull
val postId: Long
)
如果我省略comment
字段,则验证失败。
但如果我没有通过postId
,就像这样:
{
"comment": "hello"
}
验证通过。
如果未通过postId
,如何使验证失败?
P.S。我使用带有com.fasterxml.jackson.module:jackson-module-kotlin
模块的spring boot 2.0.1,kotlin版本:1.2.20
答案 0 :(得分:1)
我认为这与https://github.com/FasterXML/jackson-module-kotlin/issues/130有关。
看起来你可以打开DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES
,但这不会导致验证错误,但是它将无法构造对象。您需要适当处理该异常以生成400错误。
如果你真的想要验证,你需要允许构造对象,以便验证器可以运行,这意味着使原始字段可以为空:
data class CreateCommentRequest(
@field:NotNull
@field:NotEmpty
val comment: String,
@field:NotNull
val postId: Long?
)
这可能看似违反直觉,但验证器在构造对象之前不会运行。它不是jackson(它不关心验证注释)或kotlin的一部分。除非您提供了替代实现,否则它是基于注释进行空检查的hibernate验证器,它需要一个完整的对象才能执行此检查。
看起来jackson kotlin模块正在创建对象的实例,但它必须为postId提供一个值,因此它提供的默认值为0(除非您指示它在null基元上失败)。
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
data class Test(val x : Long)
fun main(args : Array<String>) {
val m = ObjectMapper().registerModule(KotlinModule())
print(m.readValue("{}", Test::class.java)) // prints Test(x=0)
}
通过使字段可以为空,您可以构造它,以便JSR 303验证可以在对象上运行。