1. Проверка параметров
В разработке вам часто нужно написать какой-то код для проверки поля, такого как непустые поля, ограничения длины поля, проверка формата почтового ящика и т. Д. Я лично чувствую, что при написании этих кодов есть две проблемы, которые имеют мало общего с бизнес-логикой:
Hibernate Validator (официальный документ) предоставляет относительно полный и удобный метод реализации проверки.
Пакет Spring-Boot-Starter-Web имеет пакет Hibernate-Validator, и нет необходимости обращаться к зависимости Hibernate Validator.
2. Демоверсира проверки сгибателя Validator
Давайте сначала посмотрим на простую демонстрацию, добавив аннотацию Validator:
Импорт org.hibernate.validator.constraints.notblank; импорт javax.validation.constraints.assertfalse; импорт javax.validation.constraints.pattern;
@Getter@setter@noargscstrontrupruprupublic class demomodel {@notblank (message = "Имя пользователя не может быть пустым") private String username; @Notblank (message = "Возраст не может быть пустым") @pattern (regexp = "^[0-9] {1,2} $", message = "age Infrect") частная строковая возраст; @AssertFalse (message = "Должен быть ложным") частным логическим ISFALSE; / *** Если он пуст, он не будет проверен, и если он не будет пустым, он будет проверен*/ @pattern (regexp = "^[0-9] {4}-[0-9] {2}-[0-9] {2} $", сообщение = "Дата рождения неверна")Проверка интерфейса пост, BindingResult - это набор результатов, которые не проходят проверку:
@Requestmapping ("/demo2") public void demo2 (@requestbody @valid demodel demo, bindingresult result) {if (result.haserrors ()) {for (objecterror error: result.getAllerrors ()) {System.out.println (error.getDefaultmessage (); }}} Параметры, передаваемые по запросу в сообщении :{"userName":"dd","age":120,"isFalse":true,"birthday":"21010-21-12"}
Результат вывода:
Дата рождения неверна и должна быть ложной
Неправильный возраст
Проверка параметров очень удобна. Если аннотация + проверка на поле не передается, она может заменить почерк большого количества непусты и кодов проверки ограничения поля. Ниже у нас есть более глубокое понимание того, как воспроизводить проверку параметров.
3. Режим проверки гиберната
Осторожные читатели должны были обнаружить, что в приведенном выше примере все наборы, которые не проходят проверку, возвращаются одновременно. Обычно, когда первое поле не соответствует требованиям проверки в порядке, запрос может быть отклонен напрямую. Валидатор Hibernate имеет следующие два режима проверки:
1. Нормальный режим (этот режим по умолчанию)
Нормальный режим (все атрибуты будут проверены, а затем будет возвращена вся информация об отказе от проверки)
2. Быстрая неспособность вернуться в режим
Режим возврата быстрого сбоя (возврат до тех пор, пока есть сбой проверки)
Два метода конфигурации режима проверки: (см. Официальную документацию)
Failast: True Fast Fail Redo
Valivatorfactory varidatorfactory = validation.byprovider (hibernatevalidator.class) .configure () .failfast (true) .buildvalidatorfactory (); Validator valyator = validatorfactory.getValidator ();
и (hibernate.validator.fail_fast: True Fast Fail Режим возврата False Normal Mode)
Valivatorfactory varidatorfactory = validation.byprovider (hibernatevalidator.class) .configure () .addproperty ("hibernate.validator.fail_fast", "true") .buildValidatorFactory (); Validator valyator = validatorfactory.getValidator ();4. Два типа проверки Hibernate
Настройте валидатор Hibernate для возврата режима на быстрый сбой:
@ConfigurationPublic Class ValidatorConfiguration {@Bean Public Validator Validator () {validatorFactory ValidatorFactory = validation.byProvider (hibernatevalidator.class) .configure () .AddProperty ("hibernate.validator.fail_fast", "true") .buildvalatory (); Validator valyator = validatorfactory.getValidator (); вернуть валидатор; }}1. Проверка запроса параметра
Как и в примере в демонстрации, при проверке параметров запроса добавьте @valid между демомоделем @requestbody демомоделя, а затем добавьте Bindindresult; Для нескольких параметров вы можете добавить несколько @Valid и BindingResult, например:
public void -test () ( @requestbody @valid demomodel demodel Demo, BindingResult)
@Requestmapping ("/demo2") public void demo2 (@requestbody @valid demodel demo, bindingresult result) {if (result.haserrors ()) {for (objecterror error: result.getAllerrors ()) {System.out.println (error.getDefaultmessage (); }}}2. Получить проверку параметров (@RequestParam Параметр проверки)
Используя метод проверки бобов, невозможно проверить содержание requestParam. Как правило, при обработке получает запросы (или меньше параметров), будет использоваться следующий код:
@Requestmapping (value = "/demo3", method = requestMethod.get) public void demo3 (@RequestParam (name = "grade", обязательный = true) int grade,@requestParam (name = "classroom", обязательный = true) int classroom) {System.out.println (grade + "," + classroom); }Использование аннотации @Valid для аннотирования параметров, соответствующих запросу, является недействительным. Аннотация @validated требуется, чтобы вступить в силу проверку. Как показано ниже:
а В настоящее время вам нужно использовать боб MethodValidationPostProcessor :
@Bean Public MethodValidationPostProcessor MethodValidationPostProcessor () { / ** По умолчанию является нормальный режим, и все проверки будут возвращены без прохождения сбора информации* / return New MethodValidationPostProcessor (); } Или вы можете установить валидатор для MethodValidationPostProcessor (поскольку валидатор не используется для проверки в настоящее время, конфигурация валидатора не работает)
@Bean public methodvalidationpostprocessor methodvalidationpostprocessor () {methodvalidationpostprocessor postprocessor = new MethodValidationPostProcessor (); / ** Установите режим валидатора для быстрого сбоя возврата*/ postprocessor.setValidator (valyator ()); вернуть постпроцессор; } @Bean public validator valyator () {validatorfactory valyatorfactory = validation.byprovider (hibernatevalidator.class) .configure () .addproperty ("hibernate.validator.fail_fast", "true") .buildvalidatorfactory (); Validator valyator = validatorfactory.getValidator (); вернуть валидатор; }беременный Добавьте аннотацию в контроллер, где находится метод @validated
@Requestmapping (" /validation")@restcontroller@validatedPublic Class ValidationController { /** Если есть только несколько объектов, просто напишите параметры на слое контроллера и затем проверьте их в уровне контроллера. */ @Requestmapping (value = "/ demo3", method = requestMethod.get) public void demo3 (@range (min = 1, max = 9, message = "cherge может быть только от 1-9") @requestparam (name = "grade", требуется = true) int chrade, @min (value = 1, "movie =" class minimum может быть только 1 ") @Max, value = value = 1," Class Minimum может быть 1 " 99 ") @RequestParam (name =" classroom ", обязательно = true) int classroom) {System.out.println (Grade +", " + Classroom); }}в Вернуться к подсказке информации о проверке
Вы можете увидеть: когда проверка сбой, исключение CountraintViolationException отбрасывается и обрабатывается одно и то же исключение улова:
@ControlerAdvice @componentpublic class globalexceptionHandler {@ExceptionHandler @Responsebody @ResponseStatus (httpStatus.bad_request) открытый строкальный ручки (ValidationException Exception) {if (Exception Of ExcanceViolationException) {constraintViolationExexception exs = (constraintViolationException) Exception; SET <ConstraintViolation <? >> нарушения = exs.getConstraintViolations (); для (ConstraintViolation <?> пункт: нарушения) { / ** Распечатать информацию, которая не может передать проверку* / system.out.println (item.getMessage ()); }} вернуть "плохой запрос"; }}дюймовый Проверка
Адрес запроса обслуживания браузера: http: // localhost: 8080/valyation/demo3? Grade = 18 & Classroom = 888
Выходная информация, когда метод validationPostProcessor возвращается без настройки быстрого сбоя, выглядит следующим образом:
Оценки могут быть только от 1-9
Максимальный класс может быть только 99
Когда метод validationPostProcessor настроен с быстрым возвратом сбоя, выходная информация заключается в следующем:
Оценки могут быть только от 1-9
Адрес запроса обслуживания браузера: http: // localhost: 8080/validation/demo3? Grade = 0 & classroom = 0
Выходная информация, когда метод validationPostProcessor возвращается без настройки быстрого сбоя, выглядит следующим образом:
Оценки могут быть только от 1-9
Минимальный класс может быть только 1
Когда метод validationPostProcessor настроен с быстрым возвратом сбоя, выходная информация заключается в следующем:
Оценки могут быть только от 1-9
3. Проверка модели
Модель для проверки:
@Datapublic class demo2 {@length (min = 5, max = 17, message = "Длина длины находится между [5,17]") частной длиной строки; / ** @Размер не может проверить целое число, подходящее для строки, сбора, карты и массивов*/ @size (min = 1, max = 3, message = "size между [1,3]") частной строки; @Range (min = 150, max = 250, jessall = "диапазон между [150 2550]") private int High; @Size (min = 3, max = 5, message = "Размер списка находится в [3,5]") частное список <string> list;}Проверьте модель, все следующие проверки передаются:
@Autowired Private Validator Validator; @Requestmapping ("/demo3") public void demo3 () {demo2 demo2 = new demo2 (); demo2.setage ("111"); Демо. demo2.setLength ("abcde"); demo2.setlist (new ArrayList <string> () {{add ("111"); add ("222"); add ("333");}}); SET <ConstraintViolation <demo2 >> нарушения stect = varidator.validate (demo2); for (ConstraintViolation <Demo2> Модель: нарушения) {System.out.println (model.getMessage ()); }}4. Проверка объектного каскада
Объект содержит другой объект в качестве свойства и добавьте @valid в свойство, чтобы проверить проверку внутри объекта в качестве свойства: (при проверке примера DEMO2 вы можете проверить поля DEMO2)
@Datapublic class demo2 {@size (min = 3, max = 5, message = "Размер списка находится в [3,5]") частный список <string> list; @Notnull @valid private demo3 demo3;} @datapublic class demo3 {@length (min = 5, max = 17, message = "Длина длины находится между [5,17]") частной строки extfield;}Каскадная проверка:
/ ** Бин настроен с быстрым сбоем возврата бона*/ @autowired Private Validator Validator; @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); SET <ConstraintViolation <demo2 >> нарушения stect = varidator.validate (demo2); for (ConstraintViolation <Demo2> Модель: нарушения) {System.out.println (model.getMessage ()); }}Поле Demo3 Extfield можно проверить.
5. Групповая проверка
Вывод: при проверке последовательности группировки убедитесь в указанном порядке группировки. Если предыдущая проверка не удается, последующая группировка не может быть проверена.
Существует сценарий, когда при добавлении новой пользовательской информации нет необходимости проверять пользователь (поскольку система генерируется); При изменении, пользовательский иид должен проверить пользовательский идентификатор, и может использоваться функция проверки группы пользователя в валидатор.
Установите валидатор в нормальный режим проверки ("hibernate.validator.fail_fast", "false") и используйте проверку Groupa, GroupB и модель:
Groupa, Groupb: публичный интерфейс Groupa {} public interface Groupb {}Проверьте модель: человек
@Datapublic class person {@notblank @range (min = 1, max = integer.max_value, message = "Должно быть больше 0", группы = {groupa.class}) / ** идентификатор пользователя* / private Integer userId; @Notblank @length (min = 4, max = 20, message = "Должен быть в [4,20]", группы = {groupb.class}) / ** username* / private String username; @Notblank @range (min = 0, max = 100, message = "Возраст должен быть в [0,100]", группы = {default.class}) / ** Возраст* / частное целочисленное возраст; @Range (min = 0, max = 2, message = "Пол должен быть в [0,2]", группы = {groupb.class}) /** Пол 0: неизвестно; 1: мужчина; 2: женщина*/ частное целочисленное секс;}Как показано лично выше, три группы соответственно подтверждены следующим образом:
а Группировка
Проверены только группы тегов Groupa и GroupB:
@Requestmapping ("/demo5") public void demo5 () {person p = new Person (); / ** Проверка группы не проходит*/ p.setuserid (-12); /** Groupa Verification Pass*///p.setuserid(12); p.setusername ("a"); P.Setage (110); p.setsex (5); SET <ConstraintViolation <Person >> validate = valyator.validate (p, Groupa.class, Groupb.class); для (ConstraintViolation <Person> Item: Validate) {System.out.println (item); }}или
@Requestmapping ("/demo6") public void demo6 (@validated ({groupa.class, groupb.class}) человек p, результат связывания) {if (result.haserrors ()) {list <objecterror> allerrors = result.getAllorrors (); для (objecterror error: allerrors) {System.out.println (error); }}}Если Groupa, Groupb и Default не подтверждены:
Информация о проверке следующая:
ConstraintViolationImpl {interpolatedMessage = 'должен быть в [4,20]', PropertyPath = имя пользователя, rootbeanclass = class valyator.demo.project.model.person, messageTemplate = 'должен быть в [4,20]'} constrainteviolationImpl {InterpolatedMessage = 'orever than 0'} rootpatemplean = roodpate = roodpate = roodpathean = roodpate roodpate roodpatem varidator.demo.project.model.person, messagetemplate = 'должен быть больше 0'} constraintViolationImpl {interpolatedMessage = 'Пол должен быть в [0,2]', ProportPath = Sex, RootBeanclass = valdator.demo.project.Model.person, Messageteplestrate = 'gendator.Если проверка Groupa проходит, GroupB и проверка по умолчанию не передается:
Информация о проверке следующая:
ConstraintViolationImpl {interpolatedMessage = 'должен быть в [4,20]', PropertyPath = имя пользователя, rootbeanclass = class valyator.demo.project.model.person, messagetemplate = 'должен быть в [4,20]'} constrainteviolationImpl {InterpolatedMessage = 'gender должен быть в [0,2]. rootbeanclass = class varidator.demo.project.model.person, messagetemplate = 'Пол должен быть в [0,2]'}беременный Групповая последовательность
В дополнение к указанию, следует ли проверить группой, вы также можете указать порядок проверки группы. Если проверка предыдущей группы не удается, проверка следующей группы не будет выполнена:
Последовательность указанной группы (Groupa》 GroupB》 по умолчанию):
@Group secroveence ({GroupA.Class, GroupB.Class, default.class}) Public Interface Grouporder {}Тест демо:
@Requestmapping ("/demo7") public void demo7 () {person p = new Person (); /** Проверка группы не проходит*///p.setuserid(-12); / ** Проверка проверки группы*/ p.setuserid (12); p.setusername ("a"); P.Setage (110); p.setsex (5); SET <ConstraintViolation <Person >> validate = valyator.validate (p, grouporder.class); для (ConstraintViolation <Person> Item: Validate) {System.out.println (item); }}или
@Requestmapping ("/demo8") public void demo8 (@validated ({grouporder.class}) человек p, результат связывания) {if (result.haserrors ()) {list <objecterror> allerrors = result.getallerrors (); для (objecterror error: allerrors) {System.out.println (error); }}}Если Groupa, Groupb и Default не подтверждены:
Информация о проверке следующая:
ConstraintViolationImpl {interpolatedMessage = 'Должен быть больше 0', PropertyPath = userId, rootBeanClass = Class Validator.demo.project.Model.person, MessageTemplate = 'должен быть больше 0'}Если проверка Groupa проходит, GroupB и проверка по умолчанию не передается:
Информация о проверке следующая:
ConstraintViolationImpl {interpolatedMessage = 'должен быть в [4,20]', PropertyPath = имя пользователя, rootbeanclass = class valyator.demo.project.model.person, messagetemplate = 'должен быть в [4,20]'} constrainteviolationImpl {InterpolatedMessage = 'gender должен быть в [0,2]. rootbeanclass = class varidator.demo.project.model.person, messagetemplate = 'Пол должен быть в [0,2]'}Вывод: при проверке последовательности группировки убедитесь в указанном порядке группировки. Если предыдущая проверка не удается, последующая группировка не может быть проверена.
5. Пользовательский проверчик
Вообще говоря, пользовательская проверка может решить много проблем. Но бывают и моменты, когда ситуация не может быть выполнена. В настоящее время мы можем реализовать интерфейс Validator и настроить необходимый нам валидатор.
Как показано ниже, реализуется пользовательский валидатор.
public enum casemode {overs, lower;}@target ({elementtype.method, elementtype.field, elementtype.annotation_type})@artentention (armentpolicy.runtime) @constraint (valistedby = checkcasevalidator.class) @documentedpublic @Interfice checkame {string () sefalce "; Class <?> [] Groups () default {}; Класс <? Extends Payload> [] PAYLOAD () DEFALT {}; Casemode value ();} public class checkcasevalidator реализует constraintvalidator <checkace, string> {private casemode casemode; public void инициализация (CheckAce Checkcase) {this.casemode = charecase.value (); } public boolean isvalid (String S, constraintValidatorContext constraintValidatorContext) {if (s == null) {return true; } if (casemode == casemode.upper) {return s.equals (s.touppercase ()); } else {return s.equals (s.tolowercase ()); }}}Модель для проверки:
открытый класс демонстрация {@checkcase (value = casemode.lower, message = "Имя пользователя должно быть строчной") частной строкой; public String getUsername () {return username; } public void setUsername (string username) {this.username = username; }}Конфигурация валидатора:
@Bean Public Validator Validator () {validatorFactory ValidatorFactory = valyation.ByProvider (hibernateValidator.class) .configure () .AdDProperty ("hibernate.validator.fail_fast", "true") .buildValidatorcome (); Validator valyator = validatorfactory.getValidator (); вернуть валидатор; }Проверка проверки:
@Requestmapping ("/demo4") public void demo4 () {demo demo = new demo (); demo.setusername ("имя пользователя"); SET <ConstraintViolation <demo >> validate = valyator.validate (demo); for (constraintviolation <demo> dem: validate) {System.out.println (dem.getMessage ()); }}Результат вывода:
Имя пользователя должно быть строчным
6. Общие аннотации
Встроенное ограничение в проверке бобов @null Анолированный элемент должен быть нулевым @notnull. Анноированный элемент не должен быть нулевым @AssertTrue Аннотированный элемент должен быть true @AssertFalse Аннотированный элемент должен быть ложным @min (значение). Равное указанному максимальному значению @decimalmin (значение) аннотированный элемент должен быть числом, его значение должно быть больше или равное указанному минимально Аннотированный элемент должен быть числом, и его значение должно находиться в приемлемом диапазоне @past. Аннотированный элемент должен быть датой прошлой @future Аннотированный элемент должен быть будущей датой @pattern (regex =, flag =) Аннотированный элемент должен соответствовать указанному регулярному выявлению валидатор с указанием на почту. @Length (min =, max =) Аннотированная строка должна находиться в пределах указанного диапазона @notempty Аннотированная строка должна быть не пустой @range (min =, max =, сообщение =) аннотированный элемент должен быть в пределах соответствующего диапазона // больше, чем 0,01, не содержащий 0,01 @notnull @decimalmin (значение = «0,01", включая false) private intther; 0.01@notnull@decimalmin (value = "0,01", включая = true) private bigdecimal greatorqualthan; @length (min = 1, max = 20, message = "Сообщение не может быть пустым") // не может использовать длину как диапазон //@range (min = 1, max = 20, сообщение = "Сообщение не может быть пустым") частное струнное сообщение;
7. Справочные материалы
Ссылки:
http://docs.jboss.org/hibernate/validator/4.2/reference/zh-cn/html_single/#validator-gettingstarted