Reputation: 187
Problem
Validation annotations for a Kotlin Spring Boot web project do not appear to be referenced at runtime.
@Min(18)
val age: Int? = null
Expected Result
Annotated fields should throw an error if the specified validation condition is not met.
There are a lot of questions floating around the web asking about similar issues, but the answers don't seem fix this problem.
Suggestions are typically to use "get" or "field" for the annotations - e.g.
@field:Min(18)
val age: Int? = null
Reproduction of Problem
To see why this wasn't working for Kotlin I did a comparison for Kotlin vs Java using this tutorial:
I created a Java application here:
I careated the same app in Kotlin here:
The Java app does validate the input in the webpage that runs on port 8080, but the Kotlin app does not. So the only difference appears the be the language...
Question
Upvotes: 3
Views: 1875
Reputation: 83131
In your Kotlin sample project, the position of the @Valid
annotation is incorrect. You use:
personForm: @Valid PersonForm?
This is putting the annotation on the type, a mechanism described in detail here. You're not annotating the parameter itself, which is what Spring MVC expects to trigger the validation. This is possible as the Validation API's @Valid
is defined to be usable in exactly that position. If you try to use other parameter-only annotations like @ModelAttribute
in that position, the compiler will reject that.
To resolve the problem, switch to the following declaration:
@Valid personForm: PersonForm?
This annotates the parameter, Spring MVC triggers the validation and requests sending inadequate data get redirected to the form as expected.
Alternatively, you can use Spring's @Validated
annotation instead of JSR-303's @Valid
. It essentially works the same way in this context, but prevents the misplacement as it cannot be used as type-use annotation.
Upvotes: 2
Reputation: 33121
As explained by this article:
"If you don’t specify a use-site target, the target is chosen according to the @Target annotation of the annotation being used. If there are multiple applicable targets, the first applicable target from the following list is used: param, property, field.
More information in the kotlin documentation.
Upvotes: -1