Search code examples
springspring-bootvalidationkotlin

Spring boot @Valid on requestBody in controller method not working


I am trying to validate a simple request body annotated by @Valid annotation in a @RestController annotated by @Validated. Validations are working correctly on primitive variable in request (on age in below example) but not working on pojo request body. @Valid annotation has no effect on request body Person class (i.e. controller accepting blank name and age under 18).

Person class:

import javax.validation.constraints.Min
import javax.validation.constraints.NotBlank

class Person (

    @NotBlank
    val name : String,

    @Min(18)
    val age : Int
)

Controller class:

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 HomeController {

    @GetMapping("/{age}")
    fun verifyAge(@PathVariable("age") @Min(18) age:Int): String {
        return "Eligible age."
    }

    @PostMapping
    fun personValidation(@Valid @RequestBody person : Person) : String {
        return "No validation error"
    }
}

@NotBlank, @Min and @Valid annotations came from below dependency:

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

How to make @Valid working on Person request body in a @Validated controller?


Solution

  • [Edited] This also worked for me (adding field annotation on constructor arguments) as answered by one of the user:

    import javax.validation.constraints.Min
    import javax.validation.constraints.NotBlank
    
    class Person (
    
        @field:NotBlank
        val name : String,
    
        @field:Min(18)
        val age : Int
    )
    

    Though changing the "kotlin" class definition of Person as below (constructor arguments to no-arguments) (note parentheses (...) to curly-brackets{...}) also worked without putting @field annotaion:

    import javax.validation.constraints.Min
    import javax.validation.constraints.NotBlank
    
    class Person {
    
        @NotBlank
        lateinit var name: String
    
        @Min(18)
        var age: Int = 0
    }