java - custom - spring boot validation api
Las anotaciones de javax.validation.constraints no funcionan (8)
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.
¿Qué configuración se necesita para usar las anotaciones de javax.validation.constraints
como @Size
, @NotNull
, etc.? Aquí está mi código:
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é esto no aplica restricciones para id
y name
? ¿Qué más necesito hacer?
Entonces @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í que así es como lo hice:
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);
}
}
}
Debe tener las siguientes anotaciones en el nivel del objeto si desea desencadenar la validación de ese objeto.
@Valid
@NotNull
Para que la validación de beans JSR-303 funcione en Spring, necesita varias cosas:
- Configuración del espacio de nombres MVC para anotaciones:
<mvc:annotation-driven />
- El JAR de especificaciones JSR-303:
validation-api-1.0.0.GA.jar
(parece que ya lo tienes) - Una implementación de la especificación, como Hibernate Validation, que parece ser el ejemplo más utilizado:
hibernate-validator-4.1.0.Final.jar
- En el bean a ser validado, las anotaciones de validación, ya sea desde la especificación JAR o desde la implementación JAR (que ya ha hecho)
- En el controlador que desea validar, haga una anotación en el objeto que desea validar con
@Valid
y luego incluya unBindingResult
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....
}
}
Soy bastante nuevo en Spring así que por favor toma 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 te ayudará, pero no está de más investigar esta posibilidad si también estás luchando con algunos @NotNulls que no han sido detectados.
También puede simplemente usar @NonNull
con la biblioteca lombok en su lugar, al menos para el escenario @NotNull
. Más detalles: https://projectlombok.org/api/lombok/NonNull.html
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 agregué una restricción de campo a mi clase, ya sea personalizada o estándar, la restricción de nivel de clase comenzó a funcionar.
@CustomValidation // now it works. super.
public class MyClass {
@Lob
@Column(nullable = false)
@NotBlank // adding this made @CustomValidation start working
private String name;
}
parece un comportamiento con errores para mí, pero lo suficientemente fácil de solucionar Supongo
Debe agregar @Valid a cada variable miembro , que también era un objeto que contenía restricciones de validación.
Debería llamar a un Validador en la entidad si desea validarlo. Luego obtendrá un conjunto de RestractionViolationException, que básicamente muestra para qué campo / s de su Entidad existe 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.
Tu código debería ir 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
}