Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Spring Rest validation configure property access

I have a Spring-JSON/RestAPI that use annotation driven input validation. @Valid

I get the following error when I try to validate an object inside another object.

java.lang.IllegalStateException: JSR-303 validated property 'client.application' does not have a corresponding accessor for Spring data binding - check your DataBinder's configuration (bean property versus direct field access)
    at org.springframework.validation.beanvalidation.SpringValidatorAdapter.processConstraintViolations(SpringValidatorAdapter.java:153) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:108) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.validation.DataBinder.validate(DataBinder.java:866) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    ...

Here is the json data model that is used here:

{ // @Valid MessageDTO
  "title": "Test",
  "message":"Test",
  "client": { // @Valid ClientDTO
    "application": "Test"
  }
}

I skip the java definition here since it would be too much useless noise IMO.

I don't want to/can't easily add getters or setters to my DTOs so how can I follow that error message and configure my DataBinder to use "direct field access"? I would like to use JavaConfig (@Configuration) for this.

Use use the following dependencies:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.2.4.Final</version>
</dependency>

EDIT:

Controller:

@RequestMapping(path = "/send", method = { RequestMethod.POST, RequestMethod.PUT })
public void send(@Valid @RequestBody MessageDTO message)

MessageDTO:

public class MessageDTO {

    ...

    @Valid
    @NotNull
    public ClientDTO client;

}

ClientDTO:

public class ClientDTO {

    ...

    @NotEmpty
    public String application;

}
like image 663
ST-DDT Avatar asked Aug 26 '16 10:08

ST-DDT


People also ask

How do you validate inputs in Spring Boot?

Validation in Spring Boot is done mainly by using Hibernate Validator — an implementation of Java Bean Validation using annotation based constraints. But while Hibernate provides a powerful set of constraint violations checkers out of the box, we'll need to put some effort into handling the exceptions it throws.


2 Answers

I just stumbled upon the same issue and found a solution for us and just wanna to share it.

Within the Resource or a @ControllerAdvice you can configure the Spring DataBinder to use direct field access.

@ControllerAdvice    
public class CustomControllerAdvice {

    @InitBinder
    private void activateDirectFieldAccess(DataBinder dataBinder) {
        dataBinder.initDirectFieldAccess();
    }

    ...
}
like image 60
Robert Avatar answered Sep 18 '22 17:09

Robert


For me, the solution was to add getters and setters to the DTO

public class MessageDTO {

    ...

    @Valid
    @NotNull
    public ClientDTO client;

    @NotNull public ClientDTO getClient() { return client; }
    public void setClient(@NotNull ClientDTO client) { this.client = client; }

}
like image 32
ernokstein Avatar answered Sep 21 '22 17:09

ernokstein