Spring boot @Valid on requestBody in controller method not working

六眼飞鱼酱① 提交于 2020-06-17 09:32:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!