fbpx

Validadores (Constraint) en SPRING BOOT

Si quieres validar tu objeto automáticamente en Spring Boot se puede usar “javax.validation.ConstraintValidator”. En esté post dejaré un ejemplo de cómo se puede crear uno especifico para tu proyecto.

También puedes usar los ya creados que puedes mirar aquí https://javaee.github.io/javaee-spec/javadocs/javax/validation/constraints/package-summary.html

Creando la anotación

Con la anotación @Constraint definimos la clase que va a validar nuestro campo. El método message() es el mensaje de error que se muestra en la interfaz de usuario. Finalmente, el código adicional es en su mayoría código repetitivo para cumplir con los estándares de Spring.

Una cosa a tener en cuenta es el uso de @Constraint que necesitará un validador que contenga nuestra lógica a validar, sin esto, nuestra anotación no funcionará.

En este ejemplo verificará si el campo int es mayor de edad:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({METHOD, FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = MayoriaEdadValidador.class)
@Documented
public @interface MayoriaEdad {

    String message() default "{com.programandoenjava.config.constraints.MayoriaEdad}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    int value();

}

Creando el validador

Para usar nuestra anotación, debemos crear un validado que verifique nuestra lógica, en este caso, si el valor es mayor a 18:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class MayoriaEdadValidador implements ConstraintValidator<MayoriaEdad, String> {

    private int edad;

    public void initialize(MayoriaEdad constraintAnnotation) {
        this.edad = constraintAnnotation.value();
    }

    public boolean isValid(String object, ConstraintValidatorContext constraintContext) {
        return edad > 18;
    }

}

El método initialize(…) será llamada para inicializar nuestros valores y utilizarlo en el método isValid(String object, ConstraintValidatorContext constraintContext) que será llamada para saber si nuestro valor es valido o no.

Usando nuestra anotación

Después de crearla, lo único que tenemos que hacer es añadir la anotación a nuestro pojo que usaremos para manejar nuestra petición:

import com.programandoenjava.config.constraints.MayoriaEdad;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;

public class UsuarioRequest {
    @NotBlank
    @Email
    private String email;
    private String nombre;
    @MayoriaEdad
    private Integer edad;
}

Por último, recordad que si no añadís la anotación @Validated a vuestro servicio y @Valid al parámetro que queramos validar, Spring no va a validar nuestra clase.

import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;

@Service
@Validated
public class UsuarioServicio {

    public UserResponse createUser(@Valid UserRequest userRequest) {
        // Entrará siempre y cuándo sea valido nuestro parametro "userRequest"
        return UserResponse()
    }
}

Aunque también podremos usar nuestro validador a nivel de controlador si lo prefieres:

@Controller
public class UsuarioControlador {
    
    @PostMapping("/crearusuario")
    public String submitForm(@Valid UsuarioRequest  usuarioRequest, BindingResult result, Model m) {
        if(result.hasErrors()) {
            return "inicio";
        }
        m.addAttribute("message", "Usuario creado correctamente: " + usuarioRequest.toString());
        return "inicio";
    }   
}