1. Verificação de parâmetros
No desenvolvimento, muitas vezes você precisa escrever algum código para verificação de campo, como campos não vazios, limites de comprimento de campo, verificação de formato de caixa de correio, etc. Pessoalmente, sinto que há dois problemas ao escrever esses códigos que têm pouco a ver com a lógica de negócios:
O Validador do Hibernato (documento oficial) fornece um método de implementação de verificação relativamente completo e conveniente.
O pacote Spring-Boot-Starter-Web possui o pacote de Validador de Hibernato e não há necessidade de se referir à dependência do validador de hibernato.
2. Demoção de verificação do validador de hibernato
Vamos primeiro olhar para uma demonstração simples, adicionando anotação do validador:
importar org.hibernate.validator.constraints.notblank; importar javax.validation.constraints.assertfalse; importar javax.validation.constraints.pattern;
@Getter@setter@noargsconstructorpublic classe Demomodel {@NotBlank (message = "Nome do usuário não pode estar vazio") String private String UserName; @NotBlank (message = "Age não pode estar vazio") @pattern (regexp = "^[0-9] {1,2} $", message = "Age incorreto") Age da sequência privada; @Assertfalse (message = "deve ser false") private boolean isfalse; / *** Se estiver vazio, não será verificado e, se não estiver vazio, será verificado*/ @pattern (regexp = "^[0-9] {4}-[0-9] {2}-[0-9] {2} $", mensagem = "A data do nascimento está incorreto")Verificação da interface post, BindingResult é uma coleção de resultados que não passam na verificação:
@RequestMapping ("/Demo2") public void Demo2 (@RequestBody @Valid DemOmodel Demo, BindingResult resultado) {if (result.haserrors ()) {para (objecterrror Error: resultado.getAlrorrors ()) {System.out.println (error.getDefFault: }}} Parâmetros aprovados pela solicitação de postagem :{"userName":"dd","age":120,"isFalse":true,"birthday":"21010-21-12"}
Resultado da saída:
A data de nascimento está incorreta e deve ser falsa
Idade incorreta
A verificação dos parâmetros é muito conveniente. Se a anotação + verificação no campo não for aprovada, ele poderá substituir a caligrafia de muitos códigos de verificação de restrição de campo e não vazios. Abaixo, temos uma compreensão mais profunda de como reproduzir a verificação de parâmetros.
3. Modo de verificação de hibernato
Os leitores cuidadosos devem ter descoberto que, no exemplo acima, todos os conjuntos que não passam a verificação são retornados de uma só vez. Geralmente, quando o primeiro campo não atende aos requisitos de verificação em ordem, a solicitação pode ser rejeitada diretamente. O Validador do Hibernato possui os dois modos de verificação a seguir:
1. Modo normal (este modo é padrão)
Modo Normal (todos os atributos serão verificados e, em seguida, todas as informações de falha de verificação serão retornadas)
2. Falha rápida em retornar ao modo
Modo de retorno de falha rápida (retorno desde que haja uma falha de verificação)
Dois métodos de configuração do modo de verificação: (Consulte a documentação oficial)
Failfast: verdadeiro modo de retorno de falha rápida verdadeira
ValidatorFactory validatorFactory = validation.byProvider (hibernateValidator.class) .configure () .Failfast (true) .buildValidatorFactory (); Validator validator = validatorFactory.getValidator ();
e (hibernate.validator.fail_fast: verdadeiro modo de retorno de falha rápido verdadeiro modo normal)
Validatorfactory validatorFactory = validation.byProvider (hibernateValidator.class) .configure () .addproperty ("hibernate.validator.fail_fast", "true") .bilildValidatorFactory (); Validator validator = validatorFactory.getValidator ();4. Dois tipos de verificações de hibernato
Configure o validador de hibernato para retornar o modo para falha rápida:
@ConfigurationPublic Class ValidatorConfiguration {@Bean public Validator Validator () {ValidatorFactory ValidatorFactory = Validation.ByProvider (HibernateValidator.class) .configure () .addProperty ("Hibernate.validator.Fail_Fast", "True") .Buildval (" Validator validator = validatorFactory.getValidator (); Validador de retorno; }}1. Verificação de parâmetros de solicitação
Como no exemplo na demonstração, ao verificar os parâmetros de solicitação, adicione @Valid entre a demonstração @RequestBody Demomodel e adicione o BindIndResult; Para vários parâmetros, você pode adicionar vários @Valid e BindingResult, como:
public void test () ( @requestbody @Valid Demomodel Demo, BindingResult resultado) public void test () ( @requestbody @Valid Demomodel Demo, BindingResult Result, @requestbody @valid Demomodel Demo2, BindingResult Result2)
@RequestMapping ("/Demo2") public void Demo2 (@RequestBody @Valid DemOmodel Demo, BindingResult resultado) {if (result.haserrors ()) {para (objecterrror Error: resultado.getAlrorrors ()) {System.out.println (error.getDefFault: }}}2. Obtenha verificação de parâmetros (@requestparam verificação de parâmetros)
Usando o método de verificação de feijão, não há como verificar o conteúdo do RequestParam. Geralmente, quando o processamento recebe solicitações (ou menos parâmetros), o código a seguir será usado:
@RequestMapping (Value = "/Demo3", Method = requestMethod.get) public void Demo3 (@RequestParam (name = "Grade", requerir = true) int Grade,@requestParam (name = "sala de aula", requerir = true) int aula) {System.out.println (grau + "," + Class); }Usando a anotação @valid para anotar os parâmetros correspondentes ao requestParam é inválido. A anotação @validada é necessária para fazer a verificação entrar em vigor. Como mostrado abaixo:
um. Neste momento, você precisa usar o feijão do MethodValidationPostProcessor :
@Bean Public MethodValidationPostProcessor MethodValidationPostProcessor () { / ** O padrão é o modo normal, e todas as verificações serão retornadas sem passar a coleta de informações* / Return new MethodValidationPostProcessor (); } Ou você pode definir o validador para MethodValidationPostProcessor (porque o validador não é usado para verificação no momento, a configuração do validador não funciona)
@Bean public MethodValidationPostProcessor MethodValidationPostProcessor () {MethodValidationPostProcessor Postprocessor = new MetodValidationPostProcessor (); / ** Defina o modo Validador para falha rápida retornar*/ Postprocessor.setValidator (validator ()); retornar pós -processador; } @Bean public validator validator () {validatorFactory validatorFactory = validation.byProvider (hibernateValidator.class) .configure () .addProperty ("hibernate.validator.fail_fast", "true") .buildVatorFactory (); Validator validator = validatorFactory.getValidator (); Validador de retorno; }b. Adicione anotação ao controlador onde o método está localizado @validado
@RequestMapping (" /validation")@RestController@ValidatedPublic Classe ValidationController { /** Se houver apenas alguns objetos, basta escrever os parâmetros na camada do controlador e verificá -los na camada do controlador. */ @RequestMapping(value = "/demo3", method = RequestMethod.GET) public void demo3(@Range(min = 1, max = 9, message = "Grade can only be from 1-9") @RequestParam(name = "grade", required = true) int grade, @Min(value = 1, message = "Class minimum can only be 1") @Max(value = 99, message = "Class maximum can only be 99 ") @RequestParam (name =" Classroom ", requerir = true) int aula em sala de aula) {System.out.println (grau +", " + sala de aula); }}c. Retornar ao prompt de informações de verificação
Você pode ver: quando a verificação falhar, uma exceção de restrição -violeação é lançada e a mesma exceção de captura é tratada:
@Controleradvice @componentPublic Classe GlobalexceptionHandler {@ExceptionHandler @ResponseBody @Responsestatus (httpstatus.bad_request) public string handle (validationException Exception) {if (exceção da instância de restriçãoviolationException) {) {ExceptionException) {if (If (Instância da Excepção da Excepção de Excepção) {ExceptionException; Definir <restriintiolation <? >> violações = exs.getConstraintviolations (); para (restriiviolation <?> Item: violações) { / ** Imprima as informações que não passam na verificação* / system.out.println (item.getMessage ()); }} retornar "REQUISTO RUIM"; }}d. Verificação
Endereço de solicitação de serviço do navegador: http: // localhost: 8080/validation/Demo3? Grau = 18 e sala de aula = 888
As informações de saída quando o MethodValidationPostProcessor retornou sem configurar a falha rápida é a seguinte:
As notas só podem ser de 1-9
A classe máxima pode ser apenas 99
Quando o MethodValidationPostProcessor é configurado com o retorno de falha rápida, as informações de saída são as seguintes:
As notas só podem ser de 1-9
Endereço de solicitação de serviço do navegador: http: // localhost: 8080/validation/Demo3? Grade = 0 & Classroom = 0
As informações de saída quando o MethodValidationPostProcessor retornou sem configurar a falha rápida é a seguinte:
As notas só podem ser de 1-9
A classe mínima só pode ser 1
Quando o MethodValidationPostProcessor é configurado com o retorno de falha rápida, as informações de saída são as seguintes:
As notas só podem ser de 1-9
3. Verificação do modelo
Modelo a ser verificado:
@Datapublic Classe Demo2 {@Length (min = 5, max = 17, message = "Comprimento do comprimento está entre [5,17]") Comprimento da sequência privada; / ** @tamanho não pode verificar o número inteiro, adequado para string, coleta, mapa e matrizes*/ @size (min = 1, max = 3, message = "tamanho entre [1,3]") idade de sequência privada; @Range (min = 150, max = 250, message = "intervalo está entre [150.250]") privado int alto; @Size (min = 3, max = 5, message = "O tamanho da lista está em [3,5]") Lista privada <String> Lista;}Verifique o modelo, todas as seguintes verificações são aprovadas:
@Autowired Private Validator Validator; @RequestMapping ("/Demo3") public void Demo3 () {Demo2 Demo2 = new Demo2 (); Demo2.setage ("111"); Demo2.Sethigh (150); Demo2.setLength ("ABCDE"); Demo2.SetList (novo ArrayList <String> () {{Add ("111"); Add ("222"); Add ("333");}}); SET <RestrintIolation <Demo2>> Violationset = validator.validate (Demo2); for (RestrintIolation <Mome2> Modelo: Violationset) {System.out.println (Model.getMessage ()); }}4. Verificação em cascata de objeto
O objeto contém outro objeto como uma propriedade e adicione @Valid à propriedade para verificar a verificação dentro do objeto como uma propriedade: (Ao verificar o exemplo Demo2, você pode verificar os campos da Demo2)
@Datapublic Classe Demo2 {@size (min = 3, max = 5, message = "O tamanho da lista está em [3,5]") Lista privada <String> Lista; @NotNull @Valid Private Demo3 Demo3;} @Datapublic Classe Demo3 {@Length (min = 5, max = 17, message = "O comprimento do comprimento está entre [5,17]") Private String extfield;}Verificação em cascata:
/ ** O feijão é configurado com um válido Validador privado de retorno de falha rápido*/ @aUTowired; @RequestMapping ("/Demo3") public void Demo3 () {Demo2 Demo2 = new Demo2 (); Demo2.SetList (novo ArrayList <String> () {{Add ("111"); Add ("222"); Add ("333");}}); Demo3 Demo3 = new Demo3 (); Demo3.Setextfield ("22"); Demo2.SetDemo3 (Demo3); SET <RestrintIolation <Demo2>> Violationset = validator.validate (Demo2); for (RestrintIolation <Mome2> Modelo: Violationset) {System.out.println (Model.getMessage ()); }}O campo extfield da Demo3 pode ser verificado.
5. Verificação do grupo
Conclusão: Ao verificar a sequência de agrupamento, verifique -a na ordem de agrupamento especificada. Se a verificação anterior falhar, o agrupamento subsequente não poderá ser verificado.
Há um cenário em que quando novas informações do usuário são adicionadas, não há necessidade de verificar o UserID (porque o sistema é gerado); Ao modificar, o UserID precisa verificar o UserID e a função de verificação de grupo do usuário para validador pode ser usada.
Defina o Validador no modo de verificação normal ("hibernate.validator.fail_fast", "false") e use Grupo de Verificação, Groupb e Modelo:
Grupo, GrupoB: Public Interface Groupa {} Public Interface Groupb {}Verifique o Modelo: Pessoa
@Datapublic Class Pessoa {@NotBlank @Range (min = 1, max = Integer.max_value, message = "deve ser maior que 0", grupos = {groupA.class}) / ** ID do usuário* / private Integer UserID; @NotBlank @Length (min = 4, max = 20, message = "Deve estar em [4,20]", grupos = {groupb.class}) / ** nome de usuário* / nome de string privado; @NotBlank @Range (min = 0, max = 100, message = "A idade deve estar em [0,100]", grupos = {default.class}) / ** idade* / idade inteira privada; @Range (min = 0, max = 2, message = "Gênero deve estar em [0,2]", grupos = {groupb.class}) /** gênero 0: desconhecido; 1: homem; 2: feminino*/ sexo inteiro privado;}Como mostrado pessoalmente acima, os três grupos são validados respectivamente da seguinte forma:
um. Agrupamento
Somente agrupamentos de tags de grupo e grupob são verificados:
@RequestMapping ("/Demo5") public void Demo5 () {Pessoa P = new Person (); / ** A verificação do grupo não passa*/ p.setUserID (-12); /** Pass de verificação do grupo*///p.setUserID(12); p.setusername ("A"); p.setage (110); p.setsex (5); SET <RestrintIolation <Son Pessoa>> valides = validator.validate (p, groupa.class, groupb.class); for (restriiviolation <sesso> item: validate) {System.out.println (item); }}ou
@RequestMapping ("/Demo6") public void Demo6 (@Validated ({groupA.class, Groupb.class}) Pessoa P, resultado de BindingResult) {if (resultado.haserrors ()) {list <BJecterror> allerrors = resultado.getallerrorrors (); para (erro de objecterror: allerrors) {System.out.println (erro); }}}Se GroupA, Groupb e Padrão não forem validados:
As informações de verificação são as seguintes:
RestantviolationImpl {interpolatedMessage = 'deve estar em [4,20]', PropertyPath = nome de usuário, rootbeanClass = classe valdalator.demo.project.model.person, MessGETemplate = 'deve estar em [4,20]'} restonsiolationImpl {interpolatedMessMagmage validator.demo.project.model.person, messageTemplate = 'deve ser maior que 0'} restrintiolationImpl {interpolatedMessage = 'Gênero deve estar em [0,2]', imobiliário = sexo, rootbeanClass = classe validator.demo.privect.model.person, messagemspatrplat = Class Validator.Demo.Demo.Se a verificação do grupo for aprovada, o grupob e a verificação padrão não serão aprovados:
As informações de verificação são as seguintes:
RestantViolationImpl {interpolatedMessage = 'Deve estar em [4,20]', PropertyPath = UserName, rootbeanClass = classe valdalator.demo.project.model.person, messageTemplate = 'deve estar em [4,20]'} restriolationImpl {interpolatedMagMage, 'Gender [4,20]. rootbeanClass = classe validator.demo.project.model.person, messageTemplate = 'Gênero deve estar em [0,2]'}b. Sequência de grupos
Além de especificar se deve verificar por grupo, você também pode especificar a ordem de verificação do grupo. Se a verificação do grupo anterior falhar, a verificação do próximo grupo não será realizada:
Sequência do grupo especificado (GroupA》 Groupb》 padrão):
@GroupEsequence ({groupa.class, grupob.class, default.class}) interface pública GrupoDorde {}Demonstração de teste:
@RequestMapping ("/Demo7") public void Demo7 () {Pessoa P = new Person (); /** A verificação do grupo não passa*///p.setUserID(-12); / ** Pass de verificação do grupo*/ p.setUserID (12); p.setusername ("A"); p.setage (110); p.setsex (5); SET <restantriolation <SOSED>> valides = validator.validate (p, grouporder.class); for (restriiviolation <sesso> item: validate) {System.out.println (item); }}ou
@RequestMapping ("/Demo8") public void Demo8 (@Validated ({grouporder.class}) Pessoa P, BindingResult Result) {if (resultado.haserrors ()) {list <Objecterror> allerrors = resultado.getallerrorrors (); para (erro de objecterror: allerrors) {System.out.println (erro); }}}Se GroupA, Groupb e Padrão não forem validados:
As informações de verificação são as seguintes:
RestrintiolationImpl {interpolatedMessage = 'deve ser maior que 0', PropertyPath = UserID, rootbeanClass = classe validator.demo.project.model.person, messageTemplate = 'deve ser maior que 0'}Se a verificação do grupo for aprovada, o grupob e a verificação padrão não serão aprovados:
As informações de verificação são as seguintes:
RestantViolationImpl {interpolatedMessage = 'Deve estar em [4,20]', PropertyPath = UserName, rootbeanClass = classe valdalator.demo.project.model.person, messageTemplate = 'deve estar em [4,20]'} restriolationImpl {interpolatedMagMage, 'Gender [4,20]. rootbeanClass = classe validator.demo.project.model.person, messageTemplate = 'Gênero deve estar em [0,2]'}Conclusão: Ao verificar a sequência de agrupamento, verifique -a na ordem de agrupamento especificada. Se a verificação anterior falhar, o agrupamento subsequente não poderá ser verificado.
5. Verificador personalizado
De um modo geral, a verificação personalizada pode resolver muitos problemas. Mas também há momentos em que a situação não pode ser atendida. No momento, podemos implementar a interface do validador e personalizar o validador de que precisamos.
Como mostrado abaixo, um validador de caixa personalizado é implementado:
public enum casemode {superior, inferior;}@Target ({ElementType.method, ElementType.field, ElementType.annotation_type})@retention (retentionPolicy.Runtime) @Constrant (validadoBy = checkCasealDator.class) @DocumentEdPublic @Chalcouse {StringCascaseVator.class) @DocumentEdPublic @ChonCales: Classe <?> [] Grupos () padrão {}; Classe <? estende a carga de pagamento> [] Payload () padrão {}; CASEMODE VALUE ();} classe pública CheckCaseValidator implementa o restrintValidator <cheCase, string> {private casemode casemode; public void Initialize (CHECHCASSE CHEECHCASE) {this.casemode = checkcase.value (); } public boolean isValid (string s, restrintValidatorContext restrintValidatorContext) {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 (value = casemode.lower, message = "nome de usuário deve ser minúsculo") private string userName; public String getUserName () {return Username; } public void setUserName (string userName) {this.username = nome de usuário; }}Configuração do validador:
@Bean Public Validator validator () {validatorFactory validatorFactory = validation.byProvider (hibernateValidator.class) .configure () .addProperty ("hibernate.validator.fail_fast", "true") .buildVatorFactory (); Validator validator = validatorFactory.getValidator (); Validador de retorno; }Teste de verificação:
@RequestMapping ("/Demo4") public void Demo4 () {Demo demo = new Demo (); Demo.setUsername ("Nome de usuário"); SET <restrinsiolation <Memo>> validate = validator.validate (Demo); for (restriiviolation <Memo> dem: validate) {System.out.println (dem.getMessage ()); }}Resultado da saída:
O nome de usuário deve ser minúsculo
6. Anotações comuns
The built-in constraint in Bean Validation @Null The annotated element must be null @NotNull The annotated element must not be null @AssertTrue The annotated element must be true @AssertFalse The annotated element must be false @Min(value) The annotated element must be a number, its value must be greater than or equal to the specified minimum value @Max(value) The annotated element must be a number, its value must be less than or equal to the specified maximum value @DecimalMin(value) The annotated element must be a number, its value must be greater than or equal to the specified minimum value @DecimalMax(value) The annotated element must be a number, its value must be less than or equal to the specified maximum value @Size(max=, min=) The size of the annotated element must be within the specified range @Digits (integer, fraction) The annotated O elemento deve ser um número e seu valor deve estar dentro do intervalo aceitável @past O elemento anotado deve ser uma data passada @future O elemento anotado deve ser uma data futura @pattern (regex =, sinalizador =) O elemento anotado deve atender à expressão regular de hibernate e deve ser o que é mais importante que a string de exposição regular não é mais que a string de exposição regular e a string não é maior que a string não é maior e a string não é mais importante e a string não é mais que a string não é mais que a string que não é mais que a string de exposição regular e a string não é mais que a string de exposição regular e a string não é mais que a string que não é mais que a string de exposição. @Length(min=,max=) The annotated string must be within the specified range @NotEmpty The annotated string must be non-empty @Range(min=,max=,message=) The annotated element must be within the appropriate range //Greater than 0.01, not containing 0.01@NotNull@DecimalMin(value = "0.01", including = false)private Integer greaterThan;//Greater than or equal to 0.01@notnull@decimalmin (value = "0,01", incluindo = true) privado bigdecimal Greatorequalthan; @Length (min = 1, max = 20, message = "Mensagem não pode estar vazio") // não pode usar o comprimento como intervalo // range (min = 1, max = 20, mensagem = "A mensagem não pode ser vazia") private string;
7. Materiais de referência
Referências:
http://docs.jboss.org/hibernate/validator/4.2/reference/zh-cn/html_single/#validator-gettingstarted