2012-01-06 15 views
32

¿Qué configuración se necesita para utilizar las anotaciones de javax.validation.constraints como @Size, @NotNull, etc.? Aquí está mi código:Anotaciones de javax.validation.constraints no trabajar

import javax.validation.constraints.NotNull; 
import javax.validation.constraints.Size; 

public class Person { 
     @NotNull 
     private String id; 

     @Size(max = 3) 
     private String name; 

     private int age; 

     public Person(String id, String name, int age) { 
     this.id = id; 
     this.name = name; 
     this.age = age; 
     } 
} 

Cuando trato de usarlo en otra clase, la validación no funciona (es decir, el objeto se crea sin error):

Person P = new Person(null, "Richard3", 8229)); 

¿Por qué no se aplica esto limitaciones para id y name? ¿Qué más necesito hacer?

+9

No funciona por arte de magia, debe configurar un validador. ¿En qué contexto se está ejecutando este código? – skaffman

Respuesta

38

Para JSR-303 Bean Validation para trabajar en la primavera, se necesitan varias cosas:

  1. MVC configuración de espacio de nombres para las anotaciones: <mvc:annotation-driven />
  2. El JAR de especificación JSR-303: validation-api-1.0.0.GA.jar (parece que ya lo tiene)
  3. Una implementación de la especificación, como Hibernate Valida ción, que parece ser el ejemplo más utilizado: hibernate-validator-4.1.0.Final.jar
  4. en el grano a ser validado, anotaciones de validación, ya sea desde el JAR especificaciones o del JAR aplicación (que ya lo han hecho)
  5. En el controlador se desea validar, anotar el objeto que desea validar con @Valid, y luego incluir un BindingResult en la firma del método para capturar errores.

Ejemplo:

@RequestMapping("handler.do") 
public String myHandler(@Valid @ModelAttribute("form") SomeFormBean myForm, BindingResult result, Model model) { 
    if(result.hasErrors()) { 
     ...your error handling... 
    } else { 
     ...your non-error handling.... 
    } 
} 
+0

Esto nos proporciona la configuración predeterminada del validador. Ahora, me gustaría configurar el validador antes de usarlo. ¿Dónde puedo configurarlo? ¿Alguna sobrescritura para implementar o setter para llamar? – Stephane

+2

El problema que experimenté fue que no me di cuenta de que necesitaba agregar '@ Válido' a cada variable miembro, que también era un objeto que contenía restricciones de validación. – WhiteKnight

+0

Gracias señor me salvó horas de depuración. – Chad

19

Debe usar Validator para verificar si su clase es válida.

Person person = ....; 
ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
validator = factory.getValidator(); 
Set<ConstraintViolation<Person>> violations = validator.validate(person); 

Luego, iterando infracciones establecidas, puede encontrar infracciones.

+0

Creo que este es perfectamente respondido independientemente del marco utilizado. gracias .. pero tengo una duda, ¿cómo podemos validar un parámetro que se pasa a algún método en el contexto de sin ningún marco. p.ej. 'test (@NotNull String str)', ¿podemos escribir el validador para el mismo? – agpt

5

Usted tendría que llamar a un Validador en la Entidad si desea validarlo. A continuación, obtendrá un conjunto de ConstraintViolationException, que básicamente muestra para qué campo/s de su entidad hay una violación de restricción y qué era exactamente. Quizás también pueda compartir parte del código que espera validar su entidad.

Una técnica de uso frecuente es realizar la validación en @PrePersist y la transacción de retrotracción si se usan modificaciones de datos múltiples durante la transacción o si se realizan otras acciones cuando se obtiene una excepción de validación.

El código debería ser algo así:

@PrePersist 
public void prePersist(SomeEntity someEntity){ 
    Validator validator = Validation.buildDefaultValidatorFactory.getValidator(); 
    Set<ConstraintViolation<SomeEntity>> = validator.validate(someEntity); 
    //do stuff with them, like notify client what was the wrong field, log them, or, if empty, be happy 
} 
-1

Soy bastante nuevo en Spring, por favor tome mi respuesta con un grano de sal. Tampoco pude hacer funcionar @NotNull cuando lo usé.Tenía una pantalla con campos de entrada, no la completé y moví mi pantalla hacia adelante (para eventualmente guardarla en alguna base de datos).

Estaba trabajando en mi cerebro solo para tropezar con @NotBlank también. Esa fue mi respuesta de todos modos. El campo en cuestión estaba en blanco, supongo que era "" o una cadena vacía no nula por decir. Así que el cheque de @NotBlank fue atrapado.

No estoy seguro de si eso lo ayudará, pero no está de más investigar esta posibilidad si también está luchando con algunos @NotNulls que no han sido detectados.

1

en mi caso tenía una restricción de nivel de clase personalizada que no se llamaba.

@CustomValidation // not called 
public class MyClass { 
    @Lob 
    @Column(nullable = false) 
    private String name; 
} 

tan pronto como he añadido una restricción sobre el terreno a mi clase, ya sea personalizado o estándar, la restricción de nivel de clase empezaron a trabajar.

@CustomValidation // now it works. super. 
public class MyClass { 
    @Lob 
    @Column(nullable = false) 
    @NotBlank // adding this made @CustomValidation start working 
    private String name; 
} 

parece como un comportamiento incorrecto para mí, pero lo suficientemente fácil de evitar que supongo

+0

Gracias! Estoy viendo este mismo comportamiento. – Steve

-1

es necesario agregar @Valid a cada miembro variable de, que también era un objeto que contiene la validación restricciones

0

Así que @Valid en la interfaz de servicio funcionaría solo para ese objeto. Si tiene más validaciones dentro de la jerarquía del objeto ServiceRequest, entonces podría haber activado de forma explícita las validaciones. Así es como lo he hecho:

public class ServiceRequestValidator { 

     private static Validator validator; 

     @PostConstruct 
     public void init(){ 
     validator = Validation.buildDefaultValidatorFactory().getValidator(); 
     } 

     public static <T> void validate(T t){ 
     Set<ConstraintViolation<T>> errors = validator.validate(t); 
     if(CollectionUtils.isNotEmpty(errors)){ 
      throw new ConstraintViolationException(errors); 
     } 
    } 

} 

Es necesario tener siguientes anotaciones a nivel de objeto si quiere activar la validación de ese objeto.

@Valid 
@NotNull