I’m trying to validate a POST request using Spring Validator. This is the Object I’m trying to validate:
@Validated
public class Request implements Serializable {
private static final long serialVersionUID = 1L;
private Long id1;
private Long id2;
private String s;
private List<Mapping> mappings;
public Request() {}
public Request (Long id1, Long id2, String s, List<Mapping> mappings) {
this.id1 = id1;
this.id2 = id2;
this.s = s;
this.mappings = mappings;
}
//getter() and setter() methods.
}
And this is the Mapping class:
@Validated
public class Mapping implements Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty(value="id")
private Long id;
@JsonProperty(value="string")
private String string;
@JsonProperty(value="account_id")
@NotNull
private String accountId;
@JsonProperty(value="last_updated_at")
@NotNull
private OffsetDateTime lastUpdatedAt;
// Getter and setters()
// I'll skip the getter() and setter() for id and string fields.
@Override
public String getAccountId() {
return accountId;
}
@Override
public void setAccountId (@NotNull String accountId) {
this.accountId = accountId;
}
@Override
public OffsetDateTime getLastUpdatedAt() {
return lastUpdatedAt;
}
@Override
public void setLastUpdatedAt(@NotNull OffsetDateTime lastUpdatedAt) {
this.lastUpdatedAt = lastUpdatedAt;
}
}
This is the message being posted:
[Request [id1=null, id2=null, s=6eq2J6, mappings=
[Mapping [id=2779, string=6eq2J6, accountId=null, lastUpdatedAt=null]]]]
This is how I receive the request, but the bindingResult.hasErrors() is always empty. The pushRequest is exactly as it was sent.
@RestController
@RequestMapping(value="/${path}", method={RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT})
@Validated
public class MappingController {
@PostMapping(value="/", consumes={"application/json"})
public void processMappings (@Valid @RequestBody Optional<Request> pushRequest, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
log.info("Error!");
}
}
}
Why the @NotNull
for accountId and lastUpdatedAt does not make the validation to fail when they have Null
value?
I've tried to find the solution by searching this error, the solutions was to add @Validated
to the Request, Mapping and MappingController
classes, which did not solve the problem.
Another solution was to add these Beans
to the Main()
class, which did not solve the problem.
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
//System.out.println("version: " + SpringVersion.getVersion()); // version: 5.1.0.RC1
}
@Bean
public javax.validation.Validator localValidatorFactoryBean() {
return new LocalValidatorFactoryBean();
}
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor mvProcessor = new MethodValidationPostProcessor();
mvProcessor.setValidator(validator());
return mvProcessor;
}
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setProviderClass(HibernateValidator.class);
validator.afterPropertiesSet();
return validator;
}
}
I think I found the answer thanks to this post:
jsr-303-valid-annotation-nested-object-not-working
So as soon as I added the @Valid to these fields:
@Valid
private List<Mapping> mappings;
And these fields inside Mapping:
@JsonProperty(value="account_id")
@Valid
@NotNull
private String accountId;
@JsonProperty(value="last_updated_at")
@Valid
@NotNull
private OffsetDateTime lastUpdatedAt;
The validation started working.
Also I removed the @NotNull
in the setter()
methods:
Setters() like this:
@Override
public void setAccountId (String accountId) {
this.accountId = accountId;
}
@Override
public void setLastUpdatedAt(OffsetDateTime lastUpdatedAt) {
this.lastUpdatedAt = lastUpdatedAt;
}
Also my code worked without any of the Validator beans which I added to Main().