1. Verificación de parámetros
En el desarrollo, a menudo debe escribir algún código para la verificación de campo, como campos no vacíos, límites de longitud de campo, verificación del formato de buzón, etc. Personalmente siento que hay dos problemas al escribir estos códigos que tienen poco que ver con la lógica comercial:
Hibernate Validator (documento oficial) proporciona un método de implementación de verificación relativamente completo y conveniente.
El paquete Spring-Boot-Starter-Web tiene el paquete Hibernate-Validator, y no hay necesidad de consultar la dependencia del validador Hibernate.
2. Demo de verificación de validador de hibernación
Primero veamos una demostración simple, agregando la anotación del validador:
importar org.hibernate.validator.constraints.notblank; import javax.validation.constraints.assertfalse; import javax.validation.constraints.pattern;
@Getter@setter@noargSconstructorPublic Class Demomodel {@notblank (mensaje = "Nombre de usuario no puede estar vacío") String de username de cadena privada; @Notblank (mensaje = "edad no se puede vaciar") @Pattern (regExp = "^[0-9] {1,2} $", mensaje = "Age incorrecto") Private String Age; @Assertfalse (mensaje = "debe ser falso") privado booleano isfalse; / *** Si está vacío, no se verificará, y si no está vacío, se verificará*/ @pattern (regexp = "^[0-9] {4}-[0-9] {2}-[0-9] {2} $", Message = "La fecha de nacimiento es incorrecta") CARCELA DE CARDA PRIVADA;}La verificación de la interfaz posterior, BindingResult es una colección de resultados que no pueden aprobar la verificación:
@RequestMapping ("/Demo2") public void Demo2 (@RequestBody @Valid Demomodel Demo, BindingResult Result) {if (result.haserrors ()) {for (objECTERROR ERROR: Result.getAllerrors ()) {System.out.Println (error.getDefaultMessage ()); }}} Parámetros aprobados por solicitud POST :{"userName":"dd","age":120,"isFalse":true,"birthday":"21010-21-12"}
Resultado de salida:
La fecha de nacimiento es incorrecta y debe ser falsa
Edad incorrecta
La verificación de parámetros es muy conveniente. Si no se pasa la anotación + verificación en el campo, puede reemplazar la escritura a mano de muchos códigos de verificación de restricción de campo y no vacíos. A continuación tenemos una comprensión más profunda de cómo jugar la verificación de parámetros.
3. Modo de verificación de hibernación
Los lectores cuidadosos deben haber descubierto que en el ejemplo anterior, todos los conjuntos que no logran aprobar la verificación se devuelven de inmediato. Por lo general, cuando el primer campo no cumple con los requisitos de verificación en orden, la solicitud puede ser rechazada directamente. Hibernate Validator tiene los siguientes dos modos de verificación:
1. Modo normal (este modo es predeterminado)
Modo normal (todos los atributos se verificarán y luego se devolverá toda la información de falla de verificación)
2. Falta rápida para volver al modo
Modo de retorno de falla rápida (regrese siempre que haya una falla de verificación)
Dos métodos de configuración del modo de verificación: (consulte la documentación oficial)
FailFast: verdadero Fail Fail Modo de retorno Falso Modo normal
ValidatorFactory ValidatorFactory = Validation.ByProvider (HibernateValidator.Class) .Configure () .Failfast (True) .BuildValidatorFactory (); Validator Validator = ValidatorFactory.getValidator ();
y (hibernate.validator.fail_fast: verdadero falla rápida Modo de retorno Modo normal)
ValidatorFactory ValidatorFactory = Validation.ByProvider (HibernateValidator.Class) .Configure () .AddProperty ("Hibernate.validator.fail_fast", "True") .BuildValidatorFactory (); Validator Validator = ValidatorFactory.getValidator ();4. Dos tipos de verificaciones de hibernado
Configurar el validador de Hibernate para devolver el modo a una falla rápida:
@ConfigurationPublic Class ValidatorConfiguration {@Bean Public Validator Validator () {ValidatorFactory ValidatorFactory = Validation.ByProvider (HibernateValidator.class) .Configure () .AddProperty ("Hibernate.validator.plail_asth", "True"). Validator Validator = ValidatorFactory.getValidator (); Validador de retorno; }}1. Solicitar verificación de parámetros
Como en el ejemplo en la demostración, al verificar los parámetros de solicitud, agregue @Valid entre la demostración de @RequestBody Demomodel, y luego agregue BindIndResult; Para múltiples parámetros, puede agregar múltiples @Valid y BindingResult, como:
Public void test () ( @requestbody @Valid Demomodel Demo, BindingResult Result) public void test () ( @requitionBody @Valid Demomodel Demo, BindingResult Result, @requiting @Valid Demomodel Demo2, BindingResult Result2)
@RequestMapping ("/Demo2") public void Demo2 (@RequestBody @Valid Demomodel Demo, BindingResult Result) {if (result.haserrors ()) {for (objECTERROR ERROR: Result.getAllerrors ()) {System.out.Println (error.getDefaultMessage ()); }}}2. Obtener verificación de parámetros (@RequestParam Parameter Verificación)
Utilizando el método para verificar los frijoles, no hay forma de verificar el contenido de RequestParam. En general, al procesar las solicitudes (o menos parámetros), se utilizará el siguiente código:
@RequestMapping (valor = "/demo3", método = requestmethod.get) public void Demo3 (@RequestParam (name = "grado", requerido = true) int grado,@requestparam (name = "classroom", requerido = true) int classroom) {system.println ( + " +", + classroom); }Usar la anotación @Valid para anotar los parámetros correspondientes a requestparam no es válido. Se requiere la anotación @Validated para que la verificación entre en vigencia. Como se muestra a continuación:
a. En este momento, debe usar el bean of MethodValidationPostProcessor :
@Bean Public MethodValidationPostPossor MethodValidationPostPostProcessor () { / ** El valor predeterminado es el modo normal, y todas las verificaciones se devolverán sin aprobar la recopilación de información* / return New MethodValidationPostProcessor (); } O puede establecer el validador para MethodValidationPostProcessor (porque el validador no se usa para la verificación en este momento, la configuración de validador no funciona)
@Bean Public MethodValidationPostPossor MethodValidationPostprocessor () {MethodValidationPostPossor PostProcessor = new MethodValidationPostPossor (); / ** Establezca el modo de validador en retorno de falla rápida*/ postprocessor.setValidator (validator ()); regresar postprocesador; } @Bean Public Validator Validator () {ValidatorFactory ValidatorFactory = Validation.ByProvider (HibernateValidator.class) .Configure () .AddProperty ("Hibernate.Validator.Fail_Fast", "True") .BuildValidatorFactory (); Validator Validator = ValidatorFactory.getValidator (); Validador de retorno; }b. Agregar anotación al controlador donde se encuentra el método @Validated
@RequestMapping (" /Validation")@RestController@ValidatedPublic Class ValidationController { /** Si solo hay unos pocos objetos, simplemente escriba los parámetros en la capa del controlador y luego verifíquelos en la capa del controlador. */ @RequestMapping (valor = "/ demo3", método = requestmethod.get) public void Demo3 (@Range (min = 1, max = 9, mensaje = "La calificación solo puede ser de 1-9") @RequestParam (name = "grado", requerido = true) int grado, @min (value = 1, mensaje = "class Minimum puede ser 1") @Max (value (value = 99, calcetín, @min (value = 1, Message = "Class Minimum puede ser 1") 99 ") @RequestParam (name =" Classroom ", requería = true) int classroom) {System.out.println (grado +", " + clase); }}do. Volver a la información de la información de verificación
Puede ver: cuando falla la verificación, se lanza una excepción de ExtintryViolationException y se maneja la misma excepción de captura:
@ControlerAdvice @componentPublic GlobalExceptionHandler {@ExceptionHandler @ResponseBody @ResponseStatus (httpstatus.bad_request) public String String Handle (ValidationException Exception) {If (excepción instancia de restrictViolationException) {restrictViolationException exs = (restrictViolationException) Exception; Establecer <restricticViolation <? >> violaciones = exs.getConstraintViolations (); para (restrictiveViolation <?> item: violaciones) { / ** Imprima la información que no pasa la verificación* / system.out.println (item.getMessage ()); }} return "mala solicitud"; }}d. Verificación
Dirección de solicitud de servicio del navegador: http: // localhost: 8080/validation/demo3? Grado = 18 & classroom = 888
La información de salida cuando el MethodValidationPostPossor regresó sin configurar la falla rápida es la siguiente:
Las calificaciones solo pueden ser de 1-9
La clase máxima solo puede ser 99
Cuando el método ValidationPostProcessor está configurado con el retorno de falla rápida, la información de salida es la siguiente:
Las calificaciones solo pueden ser de 1-9
Dirección de solicitud de servicio del navegador: http: // localhost: 8080/validation/demo3? Grado = 0 & classroom = 0
La información de salida cuando el MethodValidationPostPossor regresó sin configurar la falla rápida es la siguiente:
Las calificaciones solo pueden ser de 1-9
La clase mínima solo puede ser 1
Cuando el método ValidationPostProcessor está configurado con el retorno de falla rápida, la información de salida es la siguiente:
Las calificaciones solo pueden ser de 1-9
3. Verificación del modelo
Modelo a verificar:
@Datapublic de clase Demo2 {@Length (min = 5, max = 17, mensaje = "La longitud de longitud está entre [5,17]") Longitud de cadena privada; / ** El tamaño no puede verificar el entero, adecuado para cadena, colección, mapa y matrices*/ @size (min = 1, max = 3, mensaje = "tamaño entre [1,3]") edad privada de cadena; @Range (min = 150, max = 250, mensaje = "El rango está entre [150,250]") privado int high; @Size (min = 3, max = 5, mensaje = "El tamaño de la lista está en [3,5]") Lista privada <String> List;}Verifique el modelo, se pasan todas las siguientes verificaciones:
@AutoWired Validador de validador privado; @RequestMapping ("/demo3") public void demo3 () {Demo2 Demo2 = new Demo2 (); demo2.setage ("111"); demo2.sethigh (150); demo2.setLength ("abcde"); demo2.setList (new ArrayList <String> () {{add ("111"); add ("222"); add ("333");}}); Establecer <restricticViolation <MaMO2>> ViolationSet = Validator.Validate (Demo2); para (restrictiveViolation <mo2> modelo: Violationset) {System.out.println (model.getMessage ()); }}4. Verificación en cascada de objetos
El objeto contiene otro objeto como propiedad y agregue @Valid a la propiedad para verificar la verificación dentro del objeto como una propiedad: (verificar el ejemplo de Demo2, puede verificar los campos de Demo2)
@Datapublic de clase Demo2 {@size (min = 3, max = 5, mensaje = "El tamaño de la lista está en [3,5]") Lista privada <String> LIST; @Notnull @Valid Private Demo3 Demo3;} @dataPublic Class Demo3 {@Length (min = 5, max = 17, mensaje = "La longitud de la longitud está entre [5,17]") String private Extfield;}Verificación en cascada:
/ ** Bean está configurado con una falla rápida return bean*/ @autewired validador de validador privado; @RequestMapping ("/demo3") public void demo3 () {Demo2 Demo2 = new Demo2 (); demo2.setList (new ArrayList <String> () {{add ("111"); add ("222"); add ("333");}}); Demo3 demo3 = new Demo3 (); demo3.setextfield ("22"); demo2.setDemo3 (demo3); Establecer <restricticViolation <MaMO2>> ViolationSet = Validator.Validate (Demo2); para (restrictiveViolation <mo2> modelo: Violationset) {System.out.println (model.getMessage ()); }}Se puede verificar el campo Extfield de Demo3.
5. Verificación grupal
Conclusión: Al verificar la secuencia de agrupación, verifíquela en el orden de agrupación especificado. Si la verificación anterior falla, la agrupación posterior no se puede verificar.
Existe un escenario en el que cuando se agrega información sobre la nueva información del usuario, no hay necesidad de verificar el ID de usuario (porque se genera el sistema); Al modificar, el IDSED debe verificar el IDEDID, y se puede utilizar la función de verificación de grupo del usuario al validador.
Establezca el validador en modo de verificación normal ("hibernate.validator.fail_fast", "falso") y use verificación groupa, groupb y modelo:
GroupA, Groupb: Public Interface GroupA {} Public Interface Groupb {}Verificar modelo: persona
@DataPublic de clase Persona {@notblank @Range (min = 1, max = integer.max_value, mensaje = "debe ser mayor que 0", grupos = {groupa.class}) / ** ID de usuario* / privado Integer UserId; @Notblank @Length (min = 4, max = 20, mensaje = "debe estar en [4,20]", grupos = {groupb.class}) / ** nombre de usuario* / string private string username; @Notblank @range (min = 0, max = 100, mensaje = "La edad debe estar en [0,100]", grupos = {default.class}) / ** edad* / private entero edad; @Range (min = 0, max = 2, mensaje = "El género debe estar en [0,2]", grupos = {groupb.class}) /** género 0: desconocido; 1: hombre; 2: Femenino*/ Sexo Integer privado;}Como se muestra en la persona anterior, los tres grupos se validan respectivamente de la siguiente manera:
a. Agrupamiento
Solo se verifican agrupaciones de etiquetas groupa y groupb:
@RequestMapping ("/demo5") public void demo5 () {persona p = nueva persona (); / ** La verificación de GroupA no pasa*/ P.SetUserID (-12); /** Pase de verificación groupa*///p.setUserID(12); p.setUsername ("A"); P.Setage (110); p.setsex (5); Establecer <restricticViolation <OlPER>> validate = Validator.Validate (P, GroupA.Class, Groupb.Class); para (restricticViolation <Oll> item: validate) {System.out.println (item); }}o
@RequestMapping ("/Demo6") public void demo6 (@Validated ({groupA.class, groupb.class}) persona p, bindingResult date) {if (result.haserrors ()) {list <objECTERROR> allerrors = result.getAllerrors (); for (error objEcterror: alerrors) {system.out.println (error); }}}Si GroupA, Groupb y el valor predeterminado no están validados:
La información de verificación es la siguiente:
RestrictViOlationImpl {interpolatedMessage = 'debe estar en [4,20]', PropertyPath = username, rootBeanClass = class Validator.Demo.Project.Model.person, MessageTemplate = ' rootbeanClass = class Validator.demo.project.model.person, MessageTemplate = 'debe ser mayor que 0'} restrictViolationImpl {interpolatedMessage = 'gender debe estar en [0,2]', proppertyypath = sexy, rootbeanClass = class Validator.demo.project.model.person, MessageTemplate = 'Gender. [0,2] '}Si se pasa la verificación groupA, GroupB y la verificación predeterminada no se aprueba:
La información de verificación es la siguiente:
RestrictViOlationImpl {interpolatedMessage = 'debe estar en [4,20]', PropertyPath = username, rootBeanClass = class Validator.Demo.Project.Model.person, MessageTemplate = ' rootBeanClass = class Validator.Demo.Project.Model.person, MessageTemplate = 'El género debe estar en [0,2]'}b. Secuencia grupal
Además de especificar si verificar por grupo, también puede especificar el orden de verificación del grupo. Si la verificación del grupo anterior falla, la verificación del siguiente grupo no se realizará:
Secuencia del grupo especificado (groupa》 groupb》 predeterminado):
@GroupSequence ({groupa.class, groupb.class, default.class}) interface grouporder {}Demo de prueba:
@RequestMapping ("/demo7") public void demo7 () {persona p = nueva persona (); /** La verificación groupa no pasa*///p.setUserID(-12); / ** Pase de verificación groupa*/ p.setUserID (12); p.setUsername ("A"); P.Setage (110); p.setsex (5); Establecer <restricticViolation <Oll>> validate = Validator.Validate (P, GroupOrder.Class); para (restricticViolation <Oll> item: validate) {System.out.println (item); }}o
@RequestMapping ("/Demo8") public void Demo8 (@Validated ({GroupOrder.class}) Persona P, BindingResult Result) {if (result.haserrors ()) {List <BJECTERROR> ALLERRORS = result.getallerrors (); for (error objEcterror: alerrors) {system.out.println (error); }}}Si GroupA, Groupb y el valor predeterminado no están validados:
La información de verificación es la siguiente:
RestrictViolationImpl {interpolatedMessage = 'debe ser mayor que 0', PropertyPath = userId, rootBeanClass = class Validator.Demo.Project.Model.person, MessageTemplate = 'debe ser mayor que 0'}Si se pasa la verificación groupA, GroupB y la verificación predeterminada no se aprueba:
La información de verificación es la siguiente:
RestrictViOlationImpl {interpolatedMessage = 'debe estar en [4,20]', PropertyPath = username, rootBeanClass = class Validator.Demo.Project.Model.person, MessageTemplate = ' rootBeanClass = class Validator.Demo.Project.Model.person, MessageTemplate = 'El género debe estar en [0,2]'}Conclusión: Al verificar la secuencia de agrupación, verifíquela en el orden de agrupación especificado. Si la verificación anterior falla, la agrupación posterior no se puede verificar.
5. Verificador personalizado
En términos generales, la verificación personalizada puede resolver muchos problemas. Pero también hay momentos en que la situación no se puede cumplir. En este momento, podemos implementar la interfaz de validador y personalizar el validador que necesitamos.
Como se muestra a continuación, se implementa un validador de casos personalizados:
public enum Casemode {superior, bajo;}@target ({elementtype.method, elementtype.field, elementtype.annotation_type})@retention (retententPolicy.runtime) @Constraint (validatedBy = checkCaseValidator.class.class) @DocumentedPublic @interface checkcase {String Mensaje () predeterminado ";"; Clase <?> [] Grupos () predeterminado {}; Clase <? extiende la carga útil> [] Payload () predeterminado {}; CasEmode value ();} public class checkcaseValidator implementa restrictiveValidator <checkcase, string> {private CasEmode CasEmode; Public void Initialize (chechcase checkcase) {this.casemode = checkcase.value (); } public boolean isValid (String s, restrictValidatorContext restrictRintValidatorContext) {if (s == null) {return true; } if (caseMode == caseMode.upper) {return s.equals (s.ToupperCase ()); } else {return s.equals (s.tolowercase ()); }}}Modelo para verificar:
Public Class Demo {@checkcase (valor = caseMode.lower, mensaje = "UserName debe ser minúscula") Nombre de usuario de cadena privada; public String getUsername () {return UserName; } public void setUsername (String UserName) {this.Username = username; }}Configuración de validador:
@Bean Public Validator Validator () {ValidatorFactory ValidatorFactory = Validation.ByProvider (HibernateValidator.class) .Configure () .AddProperty ("Hibernate.validator.fail_fast", "True") .BuildValidatoryFactory (); Validator Validator = ValidatorFactory.getValidator (); Validador de retorno; }Prueba de verificación:
@RequestMapping ("/demo4") public void demo4 () {demo demo = new Demo (); demo.setUsername ("nombre de usuario"); Establecer <restricticViolation <MOMO>> validate = Validator.Validate (demo); para (restrictiveViolation <mo> dem: validate) {system.out.println (dem.getMessage ()); }}Resultado de salida:
El nombre de usuario debe ser en minúsculas
6. Anotaciones comunes
La restricción incorporada en la validación de frijol @null El elemento anotado debe ser nulo @notnull El elemento anotado no debe ser nulo @asserttrue El elemento anotado debe ser verdadero @assertfalse. Al valor máximo especificado @Decimalmin (valor) El elemento anotado debe ser un número, su valor debe ser mayor o igual al valor mínimo especificado @DecimalMax (valor) El elemento anotado debe ser un número, su valor debe ser menor o igual que el valor máximo especificado @size (max =, min =) el tamaño del elemento anotado debe estar dentro del rango específico especificado @Digits (intento (intento), fracción). El elemento anotado debe ser un número y su valor debe estar dentro del rango aceptable @past El elemento anotado debe ser una fecha pasada @Future El elemento anotado debe ser una fecha futura @Pattern (regex =, flag =) El elemento anotado debe cumplir con la expresión regular especificada Hibernate Validator adjunto de la restricción @notblank (mensaje =) La cadena de verificación no es mayor que sea más grande que 0 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @itread El correo electrónico El correo @Length (min =, max =) La cadena anotada debe estar dentro del rango especificado @notempty, la cadena anotada debe no ser inmoperty @Range (min =, max =, mensaje =) El elemento anotado debe estar dentro del rango apropiado // mayor que 0.01, no contener 0.01 @notnull @decimalmin (valor = "0.01", incluido = falso) en lo general, más grande; 0.01@notnull@decimalmin (valor = "0.01", incluyendo = verdadero) privado bigdecimal greatorequalthan; @Length (min = 1, max = 20, mensaje = "mensaje no puede estar vacío") // no puede usar longitud como rango //@range (min = 1, max = 20, mensaje = "mensaje no puede estar vacío") Mensaje de cadena privada;
7. Materiales de referencia
Referencias:
http://docs.jboss.org/hibernate/validator/4.2/reference/zh-cn/html_singlez/#validator-gettingstarted