Search code examples
javaspring-boothibernateinterfacehibernate-validator

Java hibernate-validator @interface load from properties


I saw following hibernate validator code

package org.hibernate.validator.constraints;
...
public @interface CreditCardNumber {
   String message() default "{org.hibernate.validator.constraints.CreditCardNumber.message}";
...
}

and in the properties files has key value the credit card error message like

org.hibernate.validator.constraints.CreditCardNumber.message        = invalid credit card number

how do hibernate validator do such things
i mean load properties on @interface?


Solution

  • Doc: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.developing-auto-configuration

    #1. create the autoconfig class

    @AutoConfiguration
    public class ObiValidatorAutoConfiguration {
    
        private MessageSource messageSource() {
            ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
            messageSource.setBasename("classpath:messages");
            messageSource.setDefaultEncoding("UTF-8");
            return messageSource;
        }
    
        @Bean
        public LocalValidatorFactoryBean getValidator() {
            LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
            bean.setValidationMessageSource(messageSource());
            return bean;
        }
    }
    

    #2. Locating Auto-configuration Candidates
    create file META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
    with content like
    package.location.ObiValidatorAutoConfiguration

    #3. create the default error message file (for ex: resources/messages.properties)
    with content
    package.cc.message=contains invalid character

    #4. the annotation class

    @Pattern(regexp = "[\\.a-zA-Z0-9]*")
    @Target({ FIELD, PARAMETER })
    @Retention(RUNTIME)
    @Constraint(validatedBy = {})
    @ReportAsSingleViolation
    public @interface CreditCard {
        String message() default "{package.cc.message}";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
    

    #5. use that annotation on spring-boot app, and when value is not valid then the default value (contains invalid character) is show up