Close

Spring Core Validation

[Last Updated: Dec 22, 2023]

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
}
1Returns true if this Validator supports the provided clazz.
2Validates the supplied target object. The supplied Errors errors instance can be used to report any resulting validation errors.
3Validate the given target object individually. Delegates to the common #validate(Object, Errors) method. Returns resulting errors from the validation of the given object @since 6.1
4Factory method to return a Validator that checks whether the target object is an instance of targetClass, applying the given delegate to populate Errors. @since 6.1
5Factory method to return a Validator that checks whether the target object's class is identical to targetClass, applying the given delegate to populate Errors. @since 6.1

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.properties

date.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");
      }
  }
}

Output

Order 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");
      }
  }
}

Output

Date cannot be empty
Price should be more than zero

Example Project

Dependencies and Technologies Used:

  • spring-context 6.1.2 (Spring Context)
     Version Compatibility: 3.2.3.RELEASE - 6.1.2Version List
    ×

    Version compatibilities of spring-context with this example:

    • 3.2.3.RELEASE
    • 3.2.4.RELEASE
    • 3.2.5.RELEASE
    • 3.2.6.RELEASE
    • 3.2.7.RELEASE
    • 3.2.8.RELEASE
    • 3.2.9.RELEASE
    • 3.2.10.RELEASE
    • 3.2.11.RELEASE
    • 3.2.12.RELEASE
    • 3.2.13.RELEASE
    • 3.2.14.RELEASE
    • 3.2.15.RELEASE
    • 3.2.16.RELEASE
    • 3.2.17.RELEASE
    • 3.2.18.RELEASE
    • 4.0.0.RELEASE
    • 4.0.1.RELEASE
    • 4.0.2.RELEASE
    • 4.0.3.RELEASE
    • 4.0.4.RELEASE
    • 4.0.5.RELEASE
    • 4.0.6.RELEASE
    • 4.0.7.RELEASE
    • 4.0.8.RELEASE
    • 4.0.9.RELEASE
    • 4.1.0.RELEASE
    • 4.1.1.RELEASE
    • 4.1.2.RELEASE
    • 4.1.3.RELEASE
    • 4.1.4.RELEASE
    • 4.1.5.RELEASE
    • 4.1.6.RELEASE
    • 4.1.7.RELEASE
    • 4.1.8.RELEASE
    • 4.1.9.RELEASE
    • 4.2.0.RELEASE
    • 4.2.1.RELEASE
    • 4.2.2.RELEASE
    • 4.2.3.RELEASE
    • 4.2.4.RELEASE
    • 4.2.5.RELEASE
    • 4.2.6.RELEASE
    • 4.2.7.RELEASE
    • 4.2.8.RELEASE
    • 4.2.9.RELEASE
    • 4.3.0.RELEASE
    • 4.3.1.RELEASE
    • 4.3.2.RELEASE
    • 4.3.3.RELEASE
    • 4.3.4.RELEASE
    • 4.3.5.RELEASE
    • 4.3.6.RELEASE
    • 4.3.7.RELEASE
    • 4.3.8.RELEASE
    • 4.3.9.RELEASE
    • 4.3.10.RELEASE
    • 4.3.11.RELEASE
    • 4.3.12.RELEASE
    • 4.3.13.RELEASE
    • 4.3.14.RELEASE
    • 4.3.15.RELEASE
    • 4.3.16.RELEASE
    • 4.3.17.RELEASE
    • 4.3.18.RELEASE
    • 4.3.19.RELEASE
    • 4.3.20.RELEASE
    • 4.3.21.RELEASE
    • 4.3.22.RELEASE
    • 4.3.23.RELEASE
    • 4.3.24.RELEASE
    • 4.3.25.RELEASE
    • 4.3.26.RELEASE
    • 4.3.27.RELEASE
    • 4.3.28.RELEASE
    • 4.3.29.RELEASE
    • 4.3.30.RELEASE
    • 5.0.0.RELEASE
    • 5.0.1.RELEASE
    • 5.0.2.RELEASE
    • 5.0.3.RELEASE
    • 5.0.4.RELEASE
    • 5.0.5.RELEASE
    • 5.0.6.RELEASE
    • 5.0.7.RELEASE
    • 5.0.8.RELEASE
    • 5.0.9.RELEASE
    • 5.0.10.RELEASE
    • 5.0.11.RELEASE
    • 5.0.12.RELEASE
    • 5.0.13.RELEASE
    • 5.0.14.RELEASE
    • 5.0.15.RELEASE
    • 5.0.16.RELEASE
    • 5.0.17.RELEASE
    • 5.0.18.RELEASE
    • 5.0.19.RELEASE
    • 5.0.20.RELEASE
    • 5.1.0.RELEASE
    • 5.1.1.RELEASE
    • 5.1.2.RELEASE
    • 5.1.3.RELEASE
    • 5.1.4.RELEASE
    • 5.1.5.RELEASE
    • 5.1.6.RELEASE
    • 5.1.7.RELEASE
    • 5.1.8.RELEASE
    • 5.1.9.RELEASE
    • 5.1.10.RELEASE
    • 5.1.11.RELEASE
    • 5.1.12.RELEASE
    • 5.1.13.RELEASE
    • 5.1.14.RELEASE
    • 5.1.15.RELEASE
    • 5.1.16.RELEASE
    • 5.1.17.RELEASE
    • 5.1.18.RELEASE
    • 5.1.19.RELEASE
    • 5.1.20.RELEASE
    • 5.2.0.RELEASE
    • 5.2.1.RELEASE
    • 5.2.2.RELEASE
    • 5.2.3.RELEASE
    • 5.2.4.RELEASE
    • 5.2.5.RELEASE
    • 5.2.6.RELEASE
    • 5.2.7.RELEASE
    • 5.2.8.RELEASE
    • 5.2.9.RELEASE
    • 5.2.10.RELEASE
    • 5.2.11.RELEASE
    • 5.2.12.RELEASE
    • 5.2.13.RELEASE
    • 5.2.14.RELEASE
    • 5.2.15.RELEASE
    • 5.2.16.RELEASE
    • 5.2.17.RELEASE
    • 5.2.18.RELEASE
    • 5.2.19.RELEASE
    • 5.2.20.RELEASE
    • 5.2.21.RELEASE
    • 5.2.22.RELEASE
    • 5.2.23.RELEASE
    • 5.2.24.RELEASE
    • 5.2.25.RELEASE
    • 5.3.0
    • 5.3.1
    • 5.3.2
    • 5.3.3
    • 5.3.4
    • 5.3.5
    • 5.3.6
    • 5.3.7
    • 5.3.8
    • 5.3.9
    • 5.3.10
    • 5.3.11
    • 5.3.12
    • 5.3.13
    • 5.3.14
    • 5.3.15
    • 5.3.16
    • 5.3.17
    • 5.3.18
    • 5.3.19
    • 5.3.20
    • 5.3.21
    • 5.3.22
    • 5.3.23
    • 5.3.24
    • 5.3.25
    • 5.3.26
    • 5.3.27
    • 5.3.28
    • 5.3.29
    • 5.3.30
    • 5.3.31
    • Compatible Java Version: 17+
    • 6.0.0
    • 6.0.1
    • 6.0.2
    • 6.0.3
    • 6.0.4
    • 6.0.5
    • 6.0.6
    • 6.0.7
    • 6.0.8
    • 6.0.9
    • 6.0.10
    • 6.0.11
    • 6.0.12
    • 6.0.13
    • 6.0.14
    • 6.0.15
    • 6.1.0
    • 6.1.1
    • 6.1.2

    Versions in green have been tested.

  • JDK 17
  • Maven 3.8.1

Spring - Using Validator Interface Select All Download
  • spring-validation-via-validator-interface
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • OrderValidator.java
          • resources

    See Also