In Spring Boot application, we can have @ConfigurationProperties classes validated via JSR-303/349 (Java EE Bean Validation specification) annotations. To make it work, we need to use Spring @Validated annotation on our configuration class. We also need to add a JSR-303/349 implementation in the classpath.
Example
Adding Hibernate validator dependency
In this example, we are going to use Hibernate validator (which is the reference implementation of JSR-303/349), so we have to add the related maven dependency:
pom.xml<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
Note that, we did not add the hibernate-validator version, that's because it is already configured in spring-boot-dependencies pom (which is the parent of spring-boot-starter-parent).
The external properties
src/main/resources/application.propertiesspring.main.banner-mode=off
spring.main.logStartupInfo=false
app.admin-contact-number=111-111-111
app.refresh-rate=0
@ConfigurationProperties class
@Component
@ConfigurationProperties("app")
@Validated
public class MyAppProperties {
@Pattern(regexp = "\\d{3}-\\d{3}-\\d{4}")
private String adminContactNumber;
@Min(1)
private int refreshRate;
.............
}
Note that, we have added @Validated annotation to turn on the validation.
Also, we purposely added such values in the external properties files, which should fail per above validation annotations. We are doing that to see whether or not the validation is performed as expected.
The Main class
@SpringBootApplication
public class ExampleMain {
public static void main(String[] args) throws InterruptedException {
ConfigurableApplicationContext context = SpringApplication.run(ExampleMain.class, args);
MyAppProperties bean = context.getBean(MyAppProperties.class);
System.out.println(bean);
}
}Output2025-10-29 14:04:34.210 INFO 14856 --- [mpleMain.main()] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@287f5654: startup date [Wed Oct 29 14:04:34 CST 2025]; root of context hierarchy 2025-10-29 14:04:34.687 WARN 14856 --- [mpleMain.main()] o.h.v.m.ParameterMessageInterpolator : HV000184: ParameterMessageInterpolator has been chosen, EL interpolation will not be supported 2025-10-29 14:04:34.822 WARN 14856 --- [mpleMain.main()] o.h.v.m.ParameterMessageInterpolator : HV000184: ParameterMessageInterpolator has been chosen, EL interpolation will not be supported 2025-10-29 14:04:34.980 ERROR 14856 --- [mpleMain.main()] o.s.b.b.PropertiesConfigurationFactory : Properties configuration failed validation 2025-10-29 14:04:34.981 ERROR 14856 --- [mpleMain.main()] o.s.b.b.PropertiesConfigurationFactory : Field error in object 'app' on field 'adminContactNumber': rejected value [111-111-111]; codes [Pattern.app.adminContactNumber,Pattern.adminContactNumber,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber,adminContactNumber]; arguments []; default message [adminContactNumber],[Ljavax.validation.constraints.Pattern$Flag;@3b68a335,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@35d1f83e]; default message [must match "\d{3}-\d{3}-\d{4}"] 2025-10-29 14:04:34.982 ERROR 14856 --- [mpleMain.main()] o.s.b.b.PropertiesConfigurationFactory : Field error in object 'app' on field 'refreshRate': rejected value [0]; codes [Min.app.refreshRate,Min.refreshRate,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.refreshRate,refreshRate]; arguments []; default message [refreshRate],1]; default message [must be greater than or equal to 1] 2025-10-29 14:04:34.984 WARN 14856 --- [mpleMain.main()] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myAppProperties': Could not bind properties to MyAppProperties (prefix=app, ignoreInvalidFields=false, ignoreUnknownFields=true, ignoreNestedProperties=false); nested exception is org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 2 errors Field error in object 'app' on field 'adminContactNumber': rejected value [111-111-111]; codes [Pattern.app.adminContactNumber,Pattern.adminContactNumber,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber,adminContactNumber]; arguments []; default message [adminContactNumber],[Ljavax.validation.constraints.Pattern$Flag;@3b68a335,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@35d1f83e]; default message [must match "\d{3}-\d{3}-\d{4}"] Field error in object 'app' on field 'refreshRate': rejected value [0]; codes [Min.app.refreshRate,Min.refreshRate,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.refreshRate,refreshRate]; arguments []; default message [refreshRate],1]; default message [must be greater than or equal to 1] 2025-10-29 14:04:35.000 INFO 14856 --- [mpleMain.main()] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. 2025-10-29 14:04:35.006 ERROR 14856 --- [mpleMain.main()] o.s.b.d.LoggingFailureAnalysisReporter :
*************************** APPLICATION FAILED TO START ***************************
Description:
Binding to target MyAppProperties{adminContactNumber='111-111-111', refreshRate=0} failed:
Property: app.adminContactNumber Value: 111-111-111 Reason: must match "\d{3}-\d{3}-\d{4}"
Property: app.refreshRate Value: 0 Reason: must be greater than or equal to 1
Action:
Update your application's configuration
[WARNING] java.lang.reflect.InvocationTargetException Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myAppProperties': Could not bind properties to MyAppProperties (prefix=app, ignoreInvalidFields=false, ignoreUnknownFields=true, ignoreNestedProperties=false); nested exception is org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 2 errors Field error in object 'app' on field 'adminContactNumber': rejected value [111-111-111]; codes [Pattern.app.adminContactNumber,Pattern.adminContactNumber,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber,adminContactNumber]; arguments []; default message [adminContactNumber],[Ljavax.validation.constraints.Pattern$Flag;@3b68a335,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@35d1f83e]; default message [must match "\d{3}-\d{3}-\d{4}"] Field error in object 'app' on field 'refreshRate': rejected value [0]; codes [Min.app.refreshRate,Min.refreshRate,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.refreshRate,refreshRate]; arguments []; default message [refreshRate],1]; default message [must be greater than or equal to 1] at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization (ConfigurationPropertiesBindingPostProcessor.java:334) at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization (ConfigurationPropertiesBindingPostProcessor.java:291) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization (AbstractAutowireCapableBeanFactory.java:409) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean (AbstractAutowireCapableBeanFactory.java:1620) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:555) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject (AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:867) at org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:543) at org.springframework.boot.SpringApplication.refresh (SpringApplication.java:693) at org.springframework.boot.SpringApplication.refreshContext (SpringApplication.java:360) at org.springframework.boot.SpringApplication.run (SpringApplication.java:303) at org.springframework.boot.SpringApplication.run (SpringApplication.java:1118) at org.springframework.boot.SpringApplication.run (SpringApplication.java:1107) at com.logicbig.example.ExampleMain.main (ExampleMain.java:11) Caused by: org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 2 errors Field error in object 'app' on field 'adminContactNumber': rejected value [111-111-111]; codes [Pattern.app.adminContactNumber,Pattern.adminContactNumber,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.adminContactNumber,adminContactNumber]; arguments []; default message [adminContactNumber],[Ljavax.validation.constraints.Pattern$Flag;@3b68a335,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@35d1f83e]; default message [must match "\d{3}-\d{3}-\d{4}"] Field error in object 'app' on field 'refreshRate': rejected value [0]; codes [Min.app.refreshRate,Min.refreshRate,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [app.refreshRate,refreshRate]; arguments []; default message [refreshRate],1]; default message [must be greater than or equal to 1] at org.springframework.boot.bind.PropertiesConfigurationFactory.checkForBindingErrors (PropertiesConfigurationFactory.java:359) at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget (PropertiesConfigurationFactory.java:276) at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget (PropertiesConfigurationFactory.java:240) at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization (ConfigurationPropertiesBindingPostProcessor.java:329) at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization (ConfigurationPropertiesBindingPostProcessor.java:291) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization (AbstractAutowireCapableBeanFactory.java:409) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean (AbstractAutowireCapableBeanFactory.java:1620) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:555) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject (AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:867) at org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:543) at org.springframework.boot.SpringApplication.refresh (SpringApplication.java:693) at org.springframework.boot.SpringApplication.refreshContext (SpringApplication.java:360) at org.springframework.boot.SpringApplication.run (SpringApplication.java:303) at org.springframework.boot.SpringApplication.run (SpringApplication.java:1118) at org.springframework.boot.SpringApplication.run (SpringApplication.java:1107) at com.logicbig.example.ExampleMain.main (ExampleMain.java:11)
Example ProjectDependencies and Technologies Used: - Spring Boot 1.5.6.RELEASE
Corresponding Spring Version 4.3.10.RELEASE - spring-boot-starter : Core starter, including auto-configuration support, logging and YAML.
- hibernate-validator 5.3.5.Final: Hibernate's Bean Validation (JSR-303) reference implementation.
- JDK 1.8
- Maven 3.3.9
|
|