Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSR-303 annotations do not validate bean properties when Spring Boot application starts

I require a properties bean to be validated at start up time and for the application to fail to start should validation fail.

I have a bean which contains configuration provided by environment variables:

@Component
public class AdminConfig
{
    @NotNull( message = "username can't be null")
    @NotEmpty( message = "username can't be empty")
    @Value(value="#{environment.username}")
    /** username to the admin portal **/
    private String username;

    @NotNull(message = "password can't be null")
    @NotEmpty(message = "password can't be empty")
    @Value(value="#{environment.password}")
    /** password to the admin portal **/
    private String password;
}

and I have a driver class:

/**
 * Driver class.
 */
@EnableAutoConfiguration
public class Main {

    /**
     * Driver method.
     * @param args Command line arguments.
     */
    public static void main(final String[] args)  {
        SpringApplication.run(Main.class, args);

    }
 }

and I have the following POM entries:

<dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>
        <!-- Validation annotations -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>
</dependencies>

When I start the application without setting the environment variables, the AdminConfig bean is created but the validation does not fire and the application starts.

I expect/require the application to fail to start because of validation failures.

like image 248
8bitjunkie Avatar asked Dec 23 '22 09:12

8bitjunkie


2 Answers

Use @Validated annotation at the AdminConfig

like image 52
Weso Avatar answered Dec 28 '22 06:12

Weso


The bean validation will occur only if it is requested. The bean instantiation does not request the validation.

The 3.8.2. Configuring a Bean Validation Provider section of the Spring documentation implies that a Validator is required to valid an instance :

Spring provides full support for the Bean Validation API. This includes convenient support for bootstrapping a JSR-303/JSR-349 Bean Validation provider as a Spring bean. This allows for a javax.validation.ValidatorFactory or javax.validation.Validator to be injected wherever validation is needed in your application.

Note that in some specific cases, the validation is requested without you need to explictly/programmatically do it. This is the case for example as you persist an entity in a Spring JPA Repository or as you invoke a Spring MVC/Rest bean method that accepts a parameter with a @Valid annotation.

In your case, you could validate the bean after its dependencies were injected by injecting and using a Validator bean (available with Spring Boot with the starter you declared in your pom.xml) :

import java.util.Set;

import javax.annotation.PostConstruct;
import javax.validation.ConstraintViolation;
import javax.validation.ValidationException;
import javax.validation.Validator;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AdminConfig{

    @Autowired
    private Validator validator;

    @NotNull( message = "username can't be null")
    @NotEmpty( message = "username can't be empty")
    private String username;

    @NotNull(message = "password can't be null")
    @NotEmpty(message = "password can't be empty")
    private String password;

    @PostConstruct
    public void init() {
        final Set<ConstraintViolation<AdminConfig>> validationErrors = validator.validate(this);
        if (!validationErrors.isEmpty()) {
            throw new ValidationException("validation errors for adminConfig bean : " + validationErrors);
        }
    }
}
like image 44
davidxxx Avatar answered Dec 28 '22 07:12

davidxxx