This example uses both org.springframework.validation.Validator and JSR 349/303 based validation annotation to perform validation.
package com.logicbig.example;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class ValidationMixedExample {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(Config.class);
ClientBean clientBean = context.getBean(ClientBean.class);
Order order = new Order();
// order.setPrice(BigDecimal.TEN);
// order.setDate(new Date(System.currentTimeMillis() + 100000));
order.setCustomerId("111");
clientBean.processOrder(order);
}
}
Output
Order has validation errors:
Date cannot be empty
No customer found with id 111
Price cannot be empty
package com.logicbig.example;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Future;
import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Date;
public class Order {
@NotNull(message = "{date.empty}")
@Future(message = "{date.future}")
private Date date;
@NotNull(message = "{price.empty}")
@DecimalMin(value = "0", inclusive = false, message = "{price.invalid}")
private BigDecimal price;
String customerId;
public void setDate(Date date) {
this.date = date;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Date getDate() {
return date;
}
public BigDecimal getPrice() {
return price;
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
@Override
public String toString() {
return "Order{ date=" + date + ", price=" + price +
", customerId='" + customerId + "'}";
}
}
package com.logicbig.example;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
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, "customerId", "customerId.empty");
Order order = (Order) target;
if (order.getCustomerId() != null) {
Customer customer = getCustomerById(order.getCustomerId());
if (customer == null) {
errors.reject("customer.id.invalid",
new Object[]{order.getCustomerId()},
"Customer id is not valid");
}
}
}
private Customer getCustomerById(String customerId) {
//just for test returning null.
// in real example the customer could be loop up in database etc.
return null;
}
}
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.BindingResult;
import org.springframework.validation.DataBinder;
import org.springframework.validation.ObjectError;
import org.springframework.validation.Validator;
import jakarta.validation.ConstraintViolation;
import java.awt.print.Book;
import java.util.Comparator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
public class GenericValidator {
@Autowired
ApplicationContext context;
/**
* This is a framework style generic method which can
* validate any object given that the corresponding
* validator is register as bean.
*/
public boolean validateObject(Object objectToValidate) {
Map<String, Validator> validatorMap = context.getBeansOfType(Validator.class);
if (validatorMap == null) {
return true;
}
DataBinder binder = new DataBinder(objectToValidate);
//in this example two validators are register OrderValidator
// and LocalValidatorFactoryBean which will do JSR 349 validations.
for (Validator validator : validatorMap.values()) {
if (validator.supports(objectToValidate.getClass())) {
binder.addValidators(validator);
}
}
binder.validate();
BindingResult bindingResult = binder.getBindingResult();
if (bindingResult.hasErrors()) {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("ValidationMessages");
System.err.println(messageSource.getMessage("object.invalid",
new Object[]{objectToValidate.getClass().getSimpleName()}, Locale.US));
bindingResult.getAllErrors()
.stream()
.map(e -> messageSource.getMessage(e, Locale.US))
.sorted(Comparator.naturalOrder())
.forEach(System.err::println);
return false;
}
return true;
}
}
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowired;
public class ClientBean {
@Autowired
private GenericValidator genericValidator;
public void processOrder(Order order) {
if (genericValidator.validateObject(order)) {
System.out.println("processing " + order);
}
}
}
package com.logicbig.example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
@Configuration
public class Config {
@Bean
public ClientBean clientBean() {
return new ClientBean();
}
@Bean
public Validator validatorFactory() {
return new LocalValidatorFactoryBean();
}
@Bean
public OrderValidator orderValidator() {
return new OrderValidator();
}
@Bean
public GenericValidator genericValidator() {
return new GenericValidator();
}
}
Original Post