Close

Spring Annotation Based Validation

[Last Updated: Dec 22, 2023]

In this tutorial we will see how to perform JSR 349/303 annotation based validation in a Spring application.

Please check out our Java EE Bean Validation tutorials if not already familiar with it.

The Spring specific class LocalValidatorFactoryBean implements jakarta.validation.Validator (formerly javax.validation.Validator), jakarta.validation.ValidatorFactory (formerly javax.validation.ValidatorFactory) and org.springframework.validation.Validator interfaces.
This class wraps standard JSR 349/303 bean validation bootstrapping process and also wraps the access around org.springframework.validation.Validator.
LocalValidatorFactoryBean allows as to inject jakarta.validation.Validator .
We can also inject org.springframework.validation.Validator instead of jakarta.validation.Validator and then in that case we will be using Spring validation API to perform validation.

Example

A bean using validation annotations

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;
    .............
}

Spring configuration

package com.logicbig.example;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

import jakarta.validation.Validator;

@Configuration
public class Config {

  @Bean
  public ClientBean clientBean() {
      return new ClientBean();
  }

  @Bean
  public Validator validatorFactory() {
      return new LocalValidatorFactoryBean();
  }
}

Performing Validation

package com.logicbig.example;

import org.springframework.beans.factory.annotation.Autowired;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validator;
import java.util.Comparator;
import java.util.Locale;
import java.util.Set;

public class ClientBean {
  @Autowired
  Validator validator;

  public void processOrder(Order order) {
      if (validateOrder(order)) {
          System.out.println("processing " + order);
      }
  }

  private boolean validateOrder(Order order) {
      Locale.setDefault(Locale.US);
      Set<ConstraintViolation<Order>> c = validator.validate(order);
      if (c.size() > 0) {
          System.err.println("Order validation errors:");
          c.stream().sorted(Comparator.comparing(v->v.getPropertyPath().toString()))
           .map(v -> v.getMessage()).forEach(System.err::println);
          return false;
      }
      return true;
  }
}

Main class

package com.logicbig.example;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.Calendar;

public class ValidationJSR349Example {

  public static void main(String[] args) {
      AnnotationConfigApplicationContext context =
              new AnnotationConfigApplicationContext(Config.class);

      Order order = new Order();
      //order.setPrice(BigDecimal.TEN);
      Calendar calendar = Calendar.getInstance();
      calendar.clear();
      calendar.set(2021,1,1, 0,0,0);
      order.setDate(calendar.getTime());

      ClientBean bean = context.getBean(ClientBean.class);
      bean.processOrder(order);
  }
}

Output

Order validation errors:
Date must be in future
Price cannot be empty

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.

  • hibernate-validator 8.0.1.Final (Hibernate's Jakarta Bean Validation reference implementation)
  • expressly 5.0.0 (Jakarta Expression Language Implementation)
  • JDK 17
  • Maven 3.8.1

Spring - Annotation based validations Select All Download
  • spring-annotation-based-validations
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • Order.java
          • resources

    See Also