Search code examples
springspring-bootkotlinspring-validation

Kotlin spring boot @RequestBody validation is not triggered


I have a problem on a project with validating @RequestBody by using

implementation("org.springframework.boot:spring-boot-starter-validation")

My DTO looks like this:

import javax.validation.constraints.Email
import javax.validation.constraints.Pattern

class LoginDto(
    @Email
    val email: String,

    @Pattern(regexp = Constants.PASSWORD_REGEX)
    val password: String
)

And Controller looks like this:

import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RestController
import javax.validation.Valid

@RestController
@Validated
class AuthController(private val authService: AuthService) {

    @PostMapping("login")
    fun login(@Valid @RequestBody loginDto: LoginDto): LoginResponse {
        return authService.login(loginDto)
    }
    ...
}

And there is no error from validation, if I try to pass invalid data:

{
    "password":"hello",
    "email":"dfdfdfdf"
}

I get no error I use Exposed instead of jpa but I think it's not related to the problem


Solution

  • You should change the annotations of @email and @Pattern to @field:Email and @field:Pattern for example.

    The reason for this is twofold, on the one hand you place the annotations on Kotlin properties, and Kotlin properties kan be accessed in a variety of ways. Therefore, you need to specify how you want to access the property to apply the annotation on. On the other hand, the annotations have a set of predefined targets. You can inspect the annotation to see for example that it has a target of field. That's why we can use the @field:Pattern and @field:Email.

    This is a key difference with java, where you have have distinct getters, setters, and fields amongst others.