5

I have a simple spring webservice that offers a @PostMapping and takes a json array of elements. I want spring to automatically validate each element in the list.

@RestController
public class PersonServlet {
    @PostMapping
    public void insertPersons(@RequestBody @Valid List<PersonDto> array) {
    }
}


public class PersonDto {
    @NotBlank
    private String firstname;

    @NotBlank
    private String lastname;
}

The following POST request should fail with a validation error that firstname is missing:

[
  {
    "lastname": "john"

  },
  {
    "firstname": "jane",
    "lastname": "doe"
  }
]

Result: the request is NOT rejected. Why?

Sidenote: if I just use PersonDto as parameter (not a list), and send a json post request with only one persons, the validation works and correctly rejects the request.

So in general the validation annotations seem to work, but just not when inside the collection!

membersound
  • 81,582
  • 193
  • 585
  • 1,120

2 Answers2

5

Workaround: the following triggers the list validation:

public class PersonDtoList extends ArrayList<PersonDto> {
      @Valid
      public List<PersonDto> getList() {
           return this;
      }
}

public void insertPersons(@RequestBody @Valid PersonDtoList array) {
}
membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • 1
    Great! This is similar to my answer and there is more specific decsription about this behaviour: https://stackoverflow.com/questions/17207766/spring-mvc-valid-on-list-of-beans-in-rest-service: @Valid is a bean validation but ArrayList is not a bean. Your PersonDtoList can be consider as a bean. – Adam Lesiak Apr 17 '18 at 13:14
0

You should add another class outside the list, for example PostCommand:

public class PostCommand() {
    @Valid
    private List<PersonDTO> list;
}

and send it on the request:

@RestController
public class PersonServlet {
    @PostMapping
    public void insertPersons(@RequestBody @Valid PostCommand postCommand) {
    }
}

and JSON will be:

{
  "list": [
            {
            "lastname": "john"
            },
            {
             "firstname": "jane",
             "lastname": "doe"
            }
         ]
}

And you will have an exception.

Adam Lesiak
  • 501
  • 4
  • 10