8

How can I tell spring-web to validate my dto without having to use getter/setter?

@PostMapping(path = "/test")
public void test(@Valid @RequestBody WebDTO dto) {

}

public class WebDTO {
   @Valid //triggers nested validation
   private List<Person> persons;

   //getter+setter for person

   @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
   public static class Person {
         @NotBlank
         public String name;
         public int age;
   }
}

Result:

"java.lang.IllegalStateException","message":"JSR-303 validated property 
    'persons[0].name' does not have a corresponding accessor for Spring data 
    binding - check your DataBinder's configuration (bean property versus direct field access)"}

Special requirement: I still want to add @AssertTrue on boolean getters to provide crossfield validation, like:

    @AssertTrue
    @XmlTransient
    @JsonIgnore
    public boolean isNameValid() {
        //...
    }
membersound
  • 81,582
  • 193
  • 585
  • 1,120

2 Answers2

10

you have to configure Spring DataBinder to use direct field access.

@ControllerAdvice    
public class ControllerAdviceConfiguration {
    @InitBinder
    private void initDirectFieldAccess(DataBinder dataBinder) {
        dataBinder.initDirectFieldAccess();
    }
}
Elgayed
  • 1,129
  • 9
  • 16
  • That worked, in general. Only downside: now the `@AssertTrue` on method-only fields cause JSR-303 validation exceptions. Because there is no local field behind those methods. Is there any chance I could combine field access, and though let spring evaluate `@AssertTrue` annotated methods not having a field? – membersound Jan 10 '19 at 15:05
-1

Try something like this:

@Access(AccessType.FIELD)
public String name;
scatolone
  • 733
  • 1
  • 5
  • 21