kotlin and @Valid Spring annotation
I have an entity:
class SomeInfo(
@NotNull @Pattern(regexp = Constraints.EMAIL_REGEX) var value: String) {
var id: Long? = null
}
And controller method:
@RequestMapping(value = "/some-info", method = RequestMethod.POST)
public Id create(@Valid @RequestBody SomeInfo someInfo) {
...
}
@Valid
annotation doesn't work.
It seems Spring needs a default parameterless constructor and fancy code above becomes in something ugly (but working) like this:
class SomeInfo() {
constructor(value: String) {
this.value = value
}
@NotNull @Pattern(regexp = Constraints.EMAIL_REGEX)
lateinit var value: String
var id: Long? = null
}
Any good practice to make it less wordy?
Thanks.
Solution 1:
Seems Spring needs these annotations to be applied to a field. But Kotlin will apply these annotations to the constructor parameter. Use field:
specifier when applying an annotation to make it apply to a field. The following code should work fine for you.
class SomeInfo(
@field:NotNull
@field:Pattern(regexp = Constraints.EMAIL_REGEX)
var value: String
) {
var id: Long? = null
}
Solution 2:
As an alternative to Michal's answer, annotating the getter also works.
class SomeInfo(
@get:NotNull
@get:Pattern(regexp = Constraints.EMAIL_REGEX)
var value: String
) {
var id: Long? = null
}
The annoying part is, that not using @get: or @field: will annotate the constructor parameter. This is still valid kotlin code (so you don't get an error). It's just useless in these use cases.
Solution 3:
If you use IntelliJ to convert Java to Kotlin, the @Valid
annotation in the Spring Controller method may eventually be attached to the type, instead of the variable. This would break the validation.
For example, the convertion could result in
@PostMapping
public Id create(@RequestBody someInfo: @Valid SomeInfo) {
...
}
This is not validating. The @Valid
has to be moved to a variable like this:
@PostMapping
public Id create(@RequestBody @Valid someInfo: SomeInfo) {
...
}
Solution 4:
Also your rest controller should be marked by @Validated
annotation
Solution 5:
For function validation of primitives:
@Validated
class MyClass() {
fun myFun(@Valid @NotEmpty @Size(min = 3, max = 30) name: String) {
}
}