Spring interface org.springframework.validation.Validator interface is used to perform validation on POJOs.
Definition of Validator(Version: spring-framework 6.1.2) package org.springframework.validation;
........
public interface Validator {
boolean supports(Class<?> clazz); 1
void validate(Object target, Errors errors); 2
default Errors validateObject(Object target) {
Errors errors = new SimpleErrors(target);
validate(target, errors);
return errors;
} 3
static <T> Validator forInstanceOf(Class<T> targetClass, BiConsumer<T, Errors> delegate) {
return new TypedValidator<>(targetClass, targetClass::isAssignableFrom, delegate);
} 4
static <T> Validator forType(Class<T> targetClass, BiConsumer<T, Errors> delegate) {
return new TypedValidator<>(targetClass, targetClass::equals, delegate);
} 5
}
How to perform validation?
Given that we have MyObjValidator which implements org.springframework.validation.Validator interface and which support MyObj:
import org.springframework.validation.DataBinder;
.....
MyObj myObj = .....
DataBinder dataBinder = new DataBinder(myObj);
dataBinder.addValidators(new MyObjValidator());
dataBinder.validate();
......
List<ObjectError> errors = dataBinder.getBindingResult().getAllErrors();
....
OR
import org.springframework.validation.DataBinder;
import org.springframework.validation.ValidationUtils;
.....
MyObj myObj = .....
BeanPropertyBindingResult result = new BeanPropertyBindingResult(myObj, "myObj");
ValidationUtils.invokeValidator(new MyObjValidator(), myObj, result);
List<ObjectError> errors = result.getAllErrors();
.....
Above code can be used in a standalone application as well (without Spring Context).
Example
An Object to be validated
package com.logicbig.example;
import java.math.BigDecimal;
import java.util.Date;
public class Order {
private Date date;
private BigDecimal price;
.............
}
Our validator implementation
package com.logicbig.example;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import java.math.BigDecimal;
public class OrderValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return Order.class == clazz;
}
@Override
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmpty(errors, "date", "date.empty");
ValidationUtils.rejectIfEmpty(errors, "price", "price.empty");
Order order = (Order) target;
if (order.getPrice() != null &&
order.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
errors.rejectValue("price", "price.invalid");
}
}
}
Resource bundle file
src/main/resources/ValidationMessages_en.propertiesdate.empty=Date cannot be empty
price.empty=Price cannot be empty
price.invalid=Price should be more than zero
date.future = Date must be in future
customerId.empty = Customer Id cannot be empty
customer.id.invalid = No customer found with id {0}
order.invalid=Order has validation errors:
object.invalid= {0} has validation errors:
Performing Validation
package com.logicbig.example;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.DataBinder;
import java.math.BigDecimal;
import java.util.Locale;
public class ValidatorExample {
public static void main(String[] args) {
Order order = new Order();
order.setPrice(BigDecimal.ZERO);
DataBinder dataBinder = new DataBinder(order);
dataBinder.addValidators(new OrderValidator());
dataBinder.validate();
if (dataBinder.getBindingResult().hasErrors()) {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("ValidationMessages");
System.err.println(messageSource.getMessage("order.invalid", null, Locale.US));
dataBinder.getBindingResult().getAllErrors().stream()
.forEach(e -> System.err.println(messageSource.getMessage(e, Locale.US)));
} else {
System.out.println("No Validation errors");
}
}
}
OutputOrder has validation errors: Date cannot be empty Price should be more than zero
In above example we used ResourceBundleMessageSource to get I18n messages from resource bundle. Please check out our tutorial on i18n if not already familiar with it.
Performing Validation by using ValidationUtils
package com.logicbig.example;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.ValidationUtils;
import java.math.BigDecimal;
import java.util.Locale;
public class ValidatorExample2 {
public static void main(String[] args) {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("ValidationMessages");
Order order = new Order();
order.setPrice(BigDecimal.ZERO);
BeanPropertyBindingResult result = new BeanPropertyBindingResult(order, "order");
ValidationUtils.invokeValidator(new OrderValidator(), order, result);
if (result.getAllErrors().size() > 0) {
result.getAllErrors().stream().
forEach(e -> System.err.println(messageSource.getMessage(e, Locale.US)));
} else {
System.out.println("No Validation errors");
}
}
}
OutputDate cannot be empty Price should be more than zero
Example ProjectDependencies and Technologies Used: - spring-context 6.1.2 (Spring Context)
Version Compatibility: 3.2.3.RELEASE - 6.1.2 Version compatibilities of spring-context with this example: Versions in green have been tested.
- JDK 17
- Maven 3.8.1
|