Validación de Bean en breve

Spring Framework proporciona soporte para la Validación de Java Bean

Bean Validation proporciona una forma común de comprobar la validez declarando restricciones y metadatos para aplicaciones Java. Para usarlo, debe anotar las propiedades del modelo de dominio con restricciones de validación declarativa, que luego el tiempo de ejecución aplica. Hay restricciones integradas, pero también puede definir sus propias restricciones.

Considere el siguiente ejemplo, que muestra un modelo PersonForm simple con dos propiedades:

Java

public class PersonForm {
    private String name;
    private int age;
}
Kotlin

class PersonForm(
        private val name: String,
        private val age: Int
)

La validación de Bean le permite declarar restricciones, como se muestra en el siguiente ejemplo:

Java

public class PersonForm {
    @NotNull
    @Size(max=64)
    private String name;
    @Min(0)
    private int age;
}
Kotlin

class PersonForm(
    @get:NotNull @get:Size(max=64)
    private val name: String,
    @get:Min(0)
    private val age: Int
)

El validador de validación de Bean luego valida instancias de esta clase según lo declarado restricciones. Para obtener información general sobre esta API, consulte "Bean Validation". Consulte la documentación del Hibernate Validator para conocer restricciones específicas. Para aprender cómo configurar un proveedor de validación de bean como Spring Bean, continúe leyendo.

Configuración de un proveedor de validación de Bean

Spring proporciona soporte completo para la API de validación de Bean, incluido el arranque del Bean. Validación del proveedor como Spring Bean. Esto le permite implementar javax.validation.ValidatorFactory o javax.validation.Validator siempre que se requiera validación en su aplicación.

Puede usar LocalValidatorFactoryBean para configurar el validador predeterminado como un Spring Bean, como se muestra en el siguiente ejemplo:

Java

import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
@Configuration
public class AppConfig {
    @Bean
    public LocalValidatorFactoryBean validator() {
        return new LocalValidatorFactoryBean();
    }
}
XML

<bean id="validator"
    class="org.springframework.validation. beanvalidation.LocalValidatorFactoryBean"/>

La configuración básica del ejemplo anterior hace que la validación del bean se inicialice utilizando el mecanismo de carga predeterminado. Un proveedor de validación de Bean, como Hibernate Validator, debe estar en el classpath y ser detectado automáticamente.

Inyección de validador

LocalValidatorFactoryBean se implementa como javax.validation.ValidatorFactory y javax.validation.Validator, así como org.springframework.validation.Validator de Spring. Puede incrustar una referencia a cualquiera de estas interfaces en beans que deberían llamar a la lógica de validación.

Puede incrustar una referencia a javax.validation.Validator si prefiere trabajar directamente con la interfaz API -Bean Validation, como se muestra en el siguiente ejemplo:

Java

import javax.validation.Validator;
@Service
public class MyService {
    @Autowired
    private Validator validator;
}
Kotlin

import javax.validation.Validator;
@Service
class MyService(@Autowired private val validator: Validator)

Puedes incrustar una referencia a org.springframework.validation.Validator, si el bean requiere la API de validación de Spring, como se muestra en el siguiente ejemplo:

Java

import org.springframework.validation.Validator;
@Service
public class MyService {
    @Autowired
    private Validator validator;
}
Kotlin

import org.springframework.validation.Validator
@Service
class MyService(@Autowired private val validator : Validator)

Configuración de restricciones personalizadas

Cada restricción de validación de bean consta de dos partes:

  • La anotación @Constraint, que declara la restricción y sus propiedades personalizadas.

  • Implementaciones de Interfaz javax.validation.ConstraintValidator, que implementa la lógica detrás de la restricción.

Para asociar la declaración con la implementación, cada anotación @Constraint hace referencia la correspondiente clase de implementación ConstraintValidator. En tiempo de ejecución, ConstraintValidatorFactory crea una instancia de una implementación a la que se hace referencia si la anotación de restricción ocurre en su modelo de dominio.

De forma predeterminada, LocalValidatorFactoryBean configura SpringConstraintValidatorFactory, que utiliza Spring para crear instancias de ConstraintValidator. Esto permite que los ConstraintValidators personalizados aprovechen la inyección de dependencia como cualquier otro Spring Bean.

El siguiente ejemplo muestra una declaración @Constraint personalizada seguida de la implementación asociada ConstraintValidator, que utiliza Spring para la inyección de dependencia:

Java

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention( RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MyConstraintValidator.class)
public @interface MyConstraint {
}
Kotlin
 
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
@Constraint(validatedBy = MyConstraintValidator::class)
annotation class MyConstraint
Java
        
import javax.validation.ConstraintValidator;
public class MyConstraintValidator implements ConstraintValidator {
    @Autowired;
    private Foo aDependency;
    // ...
}
Kotlin

import javax.validation.ConstraintValidator
class MyConstraintValidator(private val aDependency: Foo) : ConstraintValidator {
    // ...
}

Como se desprende del ejemplo anterior, la implementación ConstraintValidator puede tener su dependencias propias, marcadas con la anotación @Autowired, como cualquier otro Spring Bean.

Validación de métodos administrados por Spring

Puedes implementar la funcionalidad de validación de métodos compatible con Bean Validation 1.1 (y, como extensión especial, también Hibernate Validator 4.3), en el contexto Spring a través de la definición de MethodValidationPostProcessor:

Java

import org .springframework.validation.beanvalidation.MethodValidationPostProcessor;
@Configuration
public class AppConfig {
    @Bean
    public MethodValidationPostProcessor validationPostProcessor() {
        return new MethodValidationPostProcessor();
   }
}
XML
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/ >

Para implementar la validación de métodos administrados por Spring, todas las clases de destino deben estar anotadas con la anotación @Validated de Spring. en el que opcionalmente también se pueden declarar grupos de validación para su uso. Consulte el código MethodValidationPostProcessor para obtener más detalles sobre la configuración utilizando los proveedores Hibernate Validator y Bean Validation 1.1.

Usos de validación de métodos Proxies AOP para omitir clases de destino, ya sean proxies dinámicos del JDK para métodos en interfaces o proxies de CGLIB. Existen ciertas restricciones al utilizar un proxy. Además, recuerde que siempre debe utilizar métodos y descriptores de acceso para clases proxy; el acceso directo a los campos no funcionará.

Opciones de configuración adicionales

La configuración predeterminada de LocalValidatorFactoryBean es suficiente para la mayoría de los casos. Hay varias opciones de configuración para varias construcciones de validación de beans, desde la interpolación de mensajes hasta la habilitación del recorrido. Consulte javadoc en LocalValidatorFactoryBean para obtener más información sobre estas opciones.

Configuración de DataBinder

A partir de Spring 3, puede configure una instancia de DataBinder utilizando el Validator. Una vez configurado, puede llamar a Validator llamando a binder.validate(). Cualquier comprobación de validez de Errors se agrega automáticamente al enlace BindingResult.

El siguiente ejemplo muestra cómo utilizar mediante programación DataBinder. para llamar a las comprobaciones de validación lógica después de vincularse al objetivo:

Java

Foo target = new Foo();
DataBinder binder = new DataBinder(target);
binder.setValidator(new FooValidator());
// bind to the target object
binder.bind(propertyValues);
// validate the target
object binder.validate();
// get the BindingResult, including all validation errors
BindingResult results = binder.getBindingResult();
Kotlin

val target = Foo()
val binder = DataBinder(target)
binder.validator = FooValidator()
// bind to the target object
binder.bind(propertyValues)
// validate the target object
binder.validate()
// get the BindingResult, which includes everything validation errors
val results = binder.bindingResult

También puede configurar DataBinder usando múltiples instancias de Validator a través de dataBinder.addValidators y dataBinder.replaceValidators. Esto tiene sentido cuando se combina la validación de beans configurada globalmente con un Validator de Spring configurado localmente para una instancia de DataBinder.