Here is data class:
data class CreateCommentRequest(
@field:NotNull
@field:NotEmpty
val comment: String,
@field:NotNull
val postId: Long
)
If I omit comment
field, validation fails properly.
But if I do not pass postId
, like this:
{
"comment": "hello"
}
validation is passed.
How to make validation fail if postId
is not passed?
P.S. I use spring boot 2.0.1 with com.fasterxml.jackson.module:jackson-module-kotlin
module, kotlin version: 1.2.20
I think this is related to https://github.com/FasterXML/jackson-module-kotlin/issues/130.
It looks like you can turn on the DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES
, but that will not cause a validation error, but it will fail to construct the object. You'll need to handle that exception appropriately to generate a 400 error.
If you really want validation, you need to allow the object to be constructed, so that the validator can run, which means making the primitive fields nullable:
data class CreateCommentRequest(
@field:NotNull
@field:NotEmpty
val comment: String,
@field:NotNull
val postId: Long?
)
This probably seems counter-intuitive, but the validator doesn't run until the object is constructed. It's not part of jackson (which doesn't care about the validation annotations) or kotlin. Unless you've provided an alternative implementation, it's the hibernate validator that is doing the null checking based on the annotations, and it needs a complete object to be able to perform this checking.
It looks like the jackson kotlin module is creating an instance of the object, but it has to provide a value for the postId, so it is providing a default value of 0 (unless you instruct it to fail on null primitives).
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)
}
By making the field nullable, you're allowing it to be constructed, so that the JSR 303 validation can run on the object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With