问题
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?
回答1:
Don't mark Person as a Spring @Component.
Correct way to achieve field validation is to add @field to your properties. Example code:
class SomeRequest(
@field:NotBlank val name: String
)
This happens because Spring Boot needs this annotations to be applied on fields. Kotlin by default applied them to constructor parameter.
回答2:
You may try this option.
Please map @PostMapping with a URL like @PostMapping("/validateBody") and try with its URL. As done on https://reflectoring.io/bean-validation-with-spring-boot/
回答3:
After digging out a lot and many hit and trials for 4 days, found a simple change along with the existing correct minimal configuration. The simple change is to put a @Component annotation on Person class so that it's all the annotations could be processed as mentioned by the @Component's Spring's documentation:
Indicates that an annotated class is a "component". Such classes are considered as candidates for auto-detection when using annotation-based configuration and classpath scanning.
New person class would be as below (also changed Parameterized Person constructor to non-parameterized one in order to be processed for annotations like a Spring bean):
import org.springframework.stereotype.Component
import javax.validation.constraints.Min
import javax.validation.constraints.NotBlank
@Component
class Person {
@NotBlank
private lateinit var name : String
@Min(18)
private var age : Int = 0
}
Now with the complete minimal configuration combining both as mentioned in question and this answer, now @Valid annotations invokes on request body POJO class as per expectations and throws ConstraintViolationException as per specified constraints in Person class.
来源:https://stackoverflow.com/questions/61992596/spring-boot-valid-on-requestbody-in-controller-method-not-working