Search code examples
javaspring-mvcthymeleaf

How to do validation in Spring MVC when there's a DTO?


I have a person class and a personList DTO. The DTO is used to bind a list of persons object to the view. The user can edit one or more persons and click save to save the edits of all of them at once. Now I want to validate the new input. The problem is that the controller code "bindingResults.hasErrors()" is not returning the user input errors. I think it's because there's the personList DTO in the middle. Seems it is checking just errors in the personList class, but not in the person class as it should. How to fix that?

Model

public class Person implements Serializable{

    private static final long serialVersionUID = 1L;

    @NotEmpty(message="Name must be filled.")
    private String name;

    @Min(value=1900, message="Year is invalid")
    @Max(value=2100, message="Year is invalid")
    private int year;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

}

DTO

public class PersonList {
    
    private List<Person> personList;

    public List<Person> getPersonList() {
        return personList;
    }

    public void setPersonList(List<Person> personList) {
        this.personList = personList;
    }
}

View

<form action="person" method="post" th:object="${personListBind}">
<th:block th:each="person, itemStat : *{personList}">

    Name:
    <input type="text" th:field="*{personList[__${itemStat.index}__].name}" />

    Year:   
    <input type="text" th:field="*{personList[__${itemStat.index}__].year}" />
</th:block>
<input type="submit" name="btnSaveEdit" value="Save"/>

Controller

@RequestMapping(value = "/person", method = RequestMethod.POST)
public ModelAndView editPerson(
   @Valid @ModelAttribute PersonList personList, 
   BindingResult bindingResults) {
        
        
   if(bindingResults.hasErrors()){
      //perform action
   }

Solution

  • Found the solution for this. One simple change. Just need to add @Valid in the DTO class. This is the only line that needs to be updated: private List<@Valid Person> personList;