简体   繁体   中英

@Valid Not working @PostMapping spring boot

I am learning spring boot, I am adding Validation for @PostMapping, but somehow it always create a object even with non-valid value.

Hospital.java

public class Hospital {
    private Integer id;
    @Size(min = 2)
    private String name;
    @Size(min = 2)
    private String city;

    public Hospital(Integer id, String name, String city) {
        this.id = id;
        this.name = name;
        this.city = city;
    }

Controller

@Autowired
    HospitalData data;
...
@PostMapping("/hospital")
    public ResponseEntity<Hospital> addHospital(@Valid @RequestBody Hospital hospital){
        Hospital newHospital = data.addHospital(hospital);

        URI location = ServletUriComponentsBuilder
        .fromCurrentRequest()
        .path("/{id}")
        .buildAndExpand(newHospital.getId()).toUri();

        return ResponseEntity.created(location).build();
    }

pom.xml

<dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
        </dependency>

And previously I have added below dependency as I am using Spring 2.3.10 RELEASE, but it doesn't work, so I have added above dependency.

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

I created a Test Application reproducing the state of your code. As stated under the comments, the code you provided should definitely work. You definitely don't neet to provide a BindingResult to the method. Spring Boot throws a MethodArgumentNotValidException and therefore returns a bad request http status of the validation fails.

I created a project with following content:

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.5</version>
</parent>
<properties>
    <java.version>11</java.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

DemoEntity:

public class DemoEntity {
    @NotNull
    public String name;
    @Size(min = 3)
    public String greeting;
}

DemoController:

@Controller
public class DemoController {
    @PostMapping("/post")
    public ResponseEntity<DemoEntity> put(@Valid @RequestBody DemoEntity demoEntity) {
        return ResponseEntity.ok(demoEntity);
    }
}

Now, that's what happens with my requests:

Name Greeting Result
Peter Mr 400
Stephen Monsieur 200
Clara null 200
Jenny Madamme 200

As you see from the table above, when greeting is null the result is an ok status. If you want to guarantee that the string is at least min characters long and not null, you need to declare this explicitely.

That's, for example, if you want to validate optional fields like a mobile number. You know, it should be n numbers long and contain only numbers, but you don't want to make it mandatory. Like I showed with the greeting above.

You need to inject the BindingResult object as the param immediately following your form object and then manually check if there were any errors.

See https://spring.io/guides/gs/validating-form-input/ Create a Web Controller for a good example of how this should be done in your controller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM