- Аннотации из javax.validation.constraints не работают
- 12 ответов
- Аннотации из javax.validation.constraints не работают
- ОТВЕТЫ
- Ответ 1
- Ответ 2
- Ответ 3
- Ответ 4
- Ответ 5
- Ответ 6
- Ответ 7
- Ответ 8
- Ответ 9
- Ответ 10
- Ответ 11
- Ответ 12
- Ответ 13
- Валидация данных в Spring Boot
- Основы валидации Bean
- Настройка
- Валидация в Spring MVC Controller
- Валидация тела запроса
- Проверка переменных пути и параметров запроса
- Валидация в сервисном слое
- Валидация сущностей JPA
- Валидация конфигурации приложения
- Стандартные ограничения
- @NotNull и @Null
- @NotBlank и @NotEmpty
- Добавление пользовательского валидатора
- Принудительный вызов валидации
- Группы валидаций
- Возвращение структурных ответов на ошибки
Аннотации из javax.validation.constraints не работают
Какая конфигурация необходима для использования аннотаций от javax.validation.constraints , таких как @Size , @NotNull и т.д.? Здесь мой код:
Когда я пытаюсь использовать его в другом классе, проверка не работает (т.е. объект создается без ошибок):
Почему это не относится к ограничениям для id и name ? Что еще мне нужно сделать?
12 ответов
Для проверки JSR-303 bean для работы в Spring вам нужно несколько вещей:
- Конфигурация пространства имен MVC для аннотаций:
- JAR-303 spec JAR: validation-api-1.0.0.GA.jar (похоже, что у вас уже есть)
- Реализация спецификации, такая как Hibernate Validation, которая, как представляется, является наиболее часто используемым примером: hibernate-validator-4.1.0.Final.jar
- В bean для проверки, аннотации проверки, либо из спецификации JAR, либо из JAR реализации (который вы уже сделали)
- В обработчике, который вы хотите проверить, аннотируйте объект, который вы хотите проверить, с помощью @Valid , а затем включите BindingResult в сигнатуру метода для захвата ошибок.
Вы должны использовать Validator, чтобы проверить, действительно ли ваш класс.
Затем, при повторных нарушениях, вы можете обнаружить нарушения.
Вам нужно будет вызвать Validator в Entity, если вы хотите его проверить. Затем вы получите набор ConstraintViolationException, который в основном показывает, для какого поля /s вашего объекта существует нарушение ограничения и что именно было. Возможно, вы также можете поделиться некоторыми из кода, который вы ожидаете проверить свою сущность.
Часто используемым методом является проверка в транзакции @PrePersist и отката при использовании нескольких модификаций данных во время транзакции или других действий при получении исключения проверки.
Ваш код должен выглядеть следующим образом:
Вы также можете просто использовать @NonNull с помощью библиотеки lombok library, по крайней мере для сценария @NotNull . Подробнее: https://projectlombok.org/api/lombok/NonNull.html
в моем случае у меня было пользовательское ограничение уровня класса, которое не вызывалось.
как только я добавил ограничение на уровне поля для моего класса, как пользовательского, так и стандартного, сработало ограничение уровня класса.
мне кажется, что мне плохо, но достаточно легко обойти, я думаю,
Отличный ответ от atrain, но, возможно, лучшее решение для перехвата исключений — использовать собственный HandlerExceptionResolver и catch
@Override public ModelAndView resolException (HttpServletRequest aReq, HttpServletResponse aRes, Object aHandler, Exception anExc) <. if (anExc instanceof MethodArgumentNotValidException)//сделать вашу ошибку обработки здесь. >
Тогда вы сможете содержать своего халфлера как можно более чистым. Вам не нужно больше BindingResult, Model и SomeFormBean в myHandlerMethod
Ну, я пропустил аннотацию @Valid в моем контроллере. это сработало после этого.
Я пришел сюда несколько лет после того, как, и я мог бы исправить это благодаря atrain комментарий выше. В моем случае мне не хватало @Valid в API, который получает объект (POJO в моем случае), который был аннотирован @Size . Это решило проблему.
Мне не нужно было добавлять какие-либо дополнительные аннотации, такие как @Valid или @NotBlank к переменной, аннотированной @Size , только это ограничение в переменной и то, что я упомянул в API.
Класс Pojo:
Класс API:
для параметров метода вы можете использовать Objects.requireNonNull() следующим образом: test(String str) < Objects.requireNonNull(str); >test(String str) < Objects.requireNonNull(str); >Но это проверяется только во время выполнения и выдает NPE, если ноль. Это как проверка предварительных условий. Но это может быть то, что вы ищете.
Итак, @Valid в интерфейсе службы будет работать только для этого объекта. Если у вас есть еще какие-либо проверки в иерархии объекта ServiceRequest, вы можете явно активировать проверки. Так вот как я это сделал:
Если вы хотите вызвать проверку для этого объекта, вам необходимо иметь следующие аннотации на уровне объекта.
Вам нужно добавить @Valid в каждую переменную-член, которая также была объектом, содержащим ограничения проверки.
Я новичок в Spring, поэтому, пожалуйста, возьмите мой ответ с солью. Я также не мог заставить @NotNull работать, когда использовал его. У меня был экран с полями ввода в нем, я не заполнил его и переместил мой экран вперед (для возможного сохранения в какой-то БД).
Я ломал голову только, чтобы наткнуться на @NotBlank. Это был мой ответ. Поле, о котором идет речь, было пустым, я полагаю, что это было «» или пустая строка, не имеющая нулевого значения для каждого слова. Таким образом, проверка на @NotBlank была поймана.
Не уверен, что это поможет вам, но не может помешать расследовать эту возможность, если вы также боретесь с тем, что некоторые @NotNulls являются неотобравшимися.
Источник
Аннотации из javax.validation.constraints не работают
Какая конфигурация необходима для использования аннотаций от javax.validation.constraints , таких как @Size , @NotNull и т.д.? Здесь мой код:
Когда я пытаюсь использовать его в другом классе, проверка не работает (т.е. объект создается без ошибок):
Почему это не относится к ограничениям для id и name ? Что еще мне нужно сделать?
ОТВЕТЫ
Ответ 1
Для проверки JSR-303 bean для работы в Spring вам нужно несколько вещей:
- Конфигурация пространства имен MVC для аннотаций:
- JAR-303 spec JAR: validation-api-1.0.0.GA.jar (похоже, что у вас уже есть)
- Реализация спецификации, такая как Hibernate Validation, которая, как представляется, является наиболее часто используемым примером: hibernate-validator-4.1.0.Final.jar
- В bean для проверки, аннотации проверки, либо из спецификации JAR, либо из JAR реализации (который вы уже сделали)
- В обработчике, который вы хотите проверить, аннотируйте объект, который вы хотите проверить, с помощью @Valid , а затем включите BindingResult в сигнатуру метода для захвата ошибок.
Ответ 2
Вы должны использовать Validator, чтобы проверить, действительно ли ваш класс.
Затем, при повторных нарушениях, вы можете обнаружить нарушения.
Ответ 3
Вам нужно будет вызвать Validator в Entity, если вы хотите его проверить. Затем вы получите набор ConstraintViolationException, который в основном показывает, для какого поля /s вашего объекта существует нарушение ограничения и что именно было. Возможно, вы также можете поделиться некоторыми из кода, который вы ожидаете проверить свою сущность.
Часто используемым методом является проверка в транзакции @PrePersist и отката при использовании нескольких модификаций данных во время транзакции или других действий при получении исключения проверки.
Ваш код должен выглядеть следующим образом:
Ответ 4
Вы также можете просто использовать @NonNull с помощью библиотеки lombok library, по крайней мере для сценария @NotNull . Подробнее: https://projectlombok.org/api/lombok/NonNull.html
Ответ 5
в моем случае у меня было пользовательское ограничение уровня класса, которое не вызывалось.
как только я добавил ограничение на уровне поля для моего класса, как пользовательского, так и стандартного, сработало ограничение уровня класса.
мне кажется, что мне плохо, но достаточно легко обойти, я думаю,
Ответ 6
Я пришел сюда несколько лет после того, как, и я мог бы исправить это благодаря atrain комментарий выше. В моем случае мне не хватало @Valid в API, который получает объект (POJO в моем случае), который был аннотирован @Size . Это решило проблему.
Мне не нужно было добавлять какие-либо дополнительные аннотации, такие как @Valid или @NotBlank к переменной, аннотированной @Size , только это ограничение в переменной и то, что я упомянул в API.
Класс Pojo:
Класс API:
Ответ 7
Вам нужно добавить @Valid в каждую переменную-член, которая также была объектом, содержащим ограничения проверки.
Ответ 8
Итак, @Valid в интерфейсе службы будет работать только для этого объекта. Если у вас есть еще какие-либо проверки в иерархии объекта ServiceRequest, вы можете явно активировать проверки. Так вот как я это сделал:
Если вы хотите вызвать проверку для этого объекта, вам необходимо иметь следующие аннотации на уровне объекта.
Ответ 9
для параметров метода вы можете использовать Objects.requireNonNull() следующим образом: test(String str) < Objects.requireNonNull(str); >test(String str) < Objects.requireNonNull(str); >Но это проверяется только во время выполнения и выдает NPE, если ноль. Это как проверка предварительных условий. Но это может быть то, что вы ищете.
Ответ 10
Ну, я пропустил аннотацию @Valid в моем контроллере. это сработало после этого.
Ответ 11
Отличный ответ от atrain, но, возможно, лучшее решение для обнаружения исключений — использовать собственный HandlerExceptionResolver и поймать
Тогда вы сможете содержать ваш обработчик как можно более чистым. Вам больше не нужны BindingResult, Model и SomeFormBean в myHandlerMethod.
Ответ 12
Я новичок в Spring, поэтому, пожалуйста, возьмите мой ответ с солью. Я также не мог заставить @NotNull работать, когда использовал его. У меня был экран с полями ввода в нем, я не заполнил его и переместил мой экран вперед (для возможного сохранения в какой-то БД).
Я ломал голову только, чтобы наткнуться на @NotBlank. Это был мой ответ. Поле, о котором идет речь, было пустым, я полагаю, что это было «» или пустая строка, не имеющая нулевого значения для каждого слова. Таким образом, проверка на @NotBlank была поймана.
Не уверен, что это поможет вам, но не может помешать расследовать эту возможность, если вы также боретесь с тем, что некоторые @NotNulls являются неотобравшимися.
Ответ 13
Недавно я столкнулся с этой проблемой в очень похожей ситуации: Удовлетворил все требования в списке ответов с наивысшим рейтингом, но все же получил неправильный результат.
Поэтому я посмотрел на свои зависимости и обнаружил, что скучаю по некоторым из них. Я исправил это, добавив недостающие зависимости.
Я использовал Hibernate, необходимые зависимости были:
* Снимок, сделанный в классе «Spring & Hibernate для начинающих» @Udemy
Источник
Валидация данных в Spring Boot
Нередко пользователи пытаются передать в приложение некорректные данные. Это происходит либо из злого умысла, либо по ошибке. Поэтому стоит проверять данные на соответствие бизнес-требованиям.
Эту задачу решает Bean Validation. Он интегрирован со Spring и Spring Boot. Hibernate Validator считается эталонной реализацией Bean Validation.
Основы валидации Bean
Для проверки данных используются аннотации над полями класса. Это декларативный подход, который не загрязняет код.
При передаче размеченного таким образом объекта класса в валидатор, происходит проверка на ограничения.
Настройка
Добавьте следующие зависимости в проект:
Валидация в Spring MVC Controller
Сначала данные попадают в контроллер. У входящего HTTP-запроса возможно проверить следующие параметры:
- тело запроса
- переменные пути (например, id в /foos/
) - параметры запроса
Рассмотрим каждый из них подробнее.
Валидация тела запроса
Тело запроса POST и PUT обычно содержит данные в формате JSON. Spring автоматически сопоставляет входящий JSON с объектом Java.
Проверяем соответствует ли входящий Java объект нашим требованиям.
- Поле numberBetweenOneAndTen должно быть от 1 до 10, включительно.
- Поле ipAddress должно содержать строку в формате IP-адреса.
Контроллер REST принимает объект Input и выполняет проверку:
Достаточно добавить в параметр input аннотацию @Valid , чтобы сообщить спрингу передать объект Валидатору, прежде чем делать с ним что-либо еще.
Если класс содержит поле с другим классом, который тоже необходимо проверить — это поле необходимо пометить аннотацией Valid.
Исключение MethodArgumentNotValidException выбрасывается, когда объект не проходит проверку. По умолчанию, Spring переведет это исключение в HTTP статус 400.
Проверка переменных пути и параметров запроса
Проверка переменных пути и параметров запроса работает по-другому.
Не проверяются сложные Java-объекты, так как path-переменные и параметры запроса являются примитивными типами, такими как int , или их аналогами: Integer или String .
Вместо аннотации поля класса, как описано выше, добавляют аннотацию ограничения (в данном случае @Min ) непосредственно к параметру метода в контроллере Spring:
Обратите внимание, что необходимо добавить @Validated Spring в контроллер на уровне класса, чтобы сказать Spring проверять ограничения на параметрах метода.
В этом случае аннотация @Validated устанавливается на уровне класса, даже если она присутствует на методах.
В отличии валидации тела запроса, при неудачной проверки параметра вместо метода MethodArgumentNotValidException будет выброшен ConstraintViolationException . По умолчанию последует ответ со статусом HTTP 500 (Internal Server Error), так как Spring не регистрирует обработчик для этого исключения.
Вернем HTTP статус 400, так как клиент предоставил недействительный параметр. Для этого добавляем пользовательский обработчик исключений в контоллер:
Позже рассмотрим, как вернуть структурированный ответ об ошибке, содержащий подробности обо всех неудачных подтверждениях для проверки клиентом.
Валидация в сервисном слое
Можно проверять данные на любых компонентах Spring. Для этого используется комбинация аннотаций @Validated и @Valid .
Аннотация @Validated устанавливается только на уровне класса, так что не ставьте ее на метод в данном случае.
Валидация сущностей JPA
Persistence Layer это последняя линия проверки данных. По умолчанию Spring Data использует Hibernate, который поддерживает Bean Validation из коробки.
Обычно мы не хотим делать проверку так поздно, поскольку это означает, что бизнес-код работал с потенциально невалидными объектами, что может привести к непредвиденным ошибкам.
Допустим, необходимо хранить объекты нашего класса Input в базе данных. Сначала добавляем нужную JPA аннотацию @Entity , а так же поле id :
Когда репозиторий пытается сохранить невалидный Input , чьи аннотации ограничений нарушаются, выбрасывается ConstraintViolationException .
Bean Validation запускается Hibernate только после того как EntityManager вызовет flush.
Чтобы отключить Bean Validation в репозиториях Spring, достаточно установить свойство Spring Boot spring.jpa.properties.javax.persistence.validation.mode равным null .
Валидация конфигурации приложения
Spring Boot аннотация @ConfigurationProperties используется для связывания свойств из application.properties с Java объектом.
Данные из application необходимы для стабильной работы приложения. Bean Validation поможет обнаружить ошибку в этих данных при старте приложения.
Допустим имеется следующий конфигурационный класс:
При попытке запуска с недействительным адресом электронной почты получаем ошибку:
Стандартные ограничения
Каждая аннотация имеет следующие поля:
- message — указывает на ключ свойства в ValidationMessages.properties , который используется для отправки сообщения в случае нарушения ограничения.
- groups — позволяет определить, при каких обстоятельствах будет срабатывать эта проверка (о группах проверки поговорим позже).
- payload — позволяет определить полезную нагрузку, которая будет передаваться сс проверкой.
- @Constraint — указывает на реализацию интерфейса ConstraintValidator .
Рассмотрим популярные ограничения.
@NotNull и @Null
@NotNull — аннотированный элемент не должен быть null. Принимает любой тип.
@Null — аннотированный элемент должен быть null. Принимает любой тип.
@NotBlank и @NotEmpty
@NotBlank — аннотированный элемент не должен быть null и должен содержать хотя бы один непробельный символ. Принимает CharSequence .
@NotEmpty — аннотированный элемент не должен быть null или пустым. Поддерживаемые типы:
- CharSequence
- Collection . Оценивается размер коллекции
- Map . Оценивается размер мапы
- Array . Оценивается длина массива
@NotBlank применяется только к строкам и проверяет, что строка не пуста и не состоит только из пробелов.
@NotNull применяется к CharSequence , Collection , Map или Array и проверяет, что объект не равен null . Но при этом он может быть пуст.
@NotEmpty применяется к CharSequence , Collection , Map или Array и проверяет, что он не null имеет размер больше 0.
Аннотация @Size(min=6) пропустит строку состоящую из 6 пробелов и/или символов переноса строки, а @NotBlank не пропустит.
Размер аннотированного элемента должен быть между указанными границами, включая сами границы. null элементы считаются валидными.
- CharSequence . Оценивается длина последовательности символов
- Collection . Оценивается размер коллекции
- Map . Оценивается размер мапы
- Array . Оценивается длина массива
Добавление пользовательского валидатора
Если имеющихся аннотаций ограничений недостаточно, то создайте новые.
В классе Input использовалось регулярное выражение для проверки того, что строка является IP адресом. Регулярное выражение не является полным: оно позволяет сокеты со значениями больше 255, таким образом «111.111.111.333» будет считаться действительным.
Давайте напишем валидатор, который реализует эту проверку на Java. Потому что как говорится, до решения проблемы регулярным выражением у вас была одна проблема, а теперь стало двe 🙂
Сначала создаем пользовательскую аннотацию @IpAddress :
Реализация валидатора выглядит следующим образом:
Теперь можно использовать аннотацию @IpAddress , как и любую другую аннотацию ограничения.
Принудительный вызов валидации
Для принудительного вызова проверки, без использования Spring Boot, создайте валидатор вручную.
Тем не менее, Spring Boot предоставляет предварительно сконфигурированный экземпляр валидатора. Внедрив этот экземпляр в сервис не придется создавать его вручную.
Когда этот сервис внедряется Spring, в конструктор автоматически вставляется экземпляр валидатора.
Группы валидаций
Некоторые объекты участвуют в разных вариантах использования.
Возьмем типичные операции CRUD: при обновлении и создании, скорее всего, будет использоваться один и тот же класс. Тем не менее, некоторые валидации должны срабатывать при различных обстоятельствах:
- только перед созданием
- только перед обновлением
- или в обоих случаях
Функция Bean Validation, которая позволяет нам внедрять такие правила проверки, называется «Validation Groups».
Все аннотации ограничений должны иметь поле groups . Это поле быть использовано для передачи любых классов, каждый из которых определяет группу проверки.
Для нашего примера CRUD определим два маркерных интерфейса OnCreate и OnUpdate :
Затем используем эти интерфейсы с любой аннотацией ограничения:
Это позволит убедиться, что id пуст при создании и заполнен при обновлении.
Spring поддерживает группы проверки только с аннотацией @Validated
Обратите внимание, что аннотация @Validated применяется ко всему классу. Чтобы определить, какая группа проверки активна, она также применяется на уровне метода.
Использование групп проверки может легко стать анти-паттерном. При использовании групп валидации сущность должна знать правила валидации для всех случаев использования (групп), в которых она используется.
Возвращение структурных ответов на ошибки
Когда проверка не удается, лучше вернуть клиенту понятное сообщение об ошибке. Для этого необходимо вернуть структуру данных с сообщением об ошибке для каждой проверки, которая не прошла валидацию.
Сначала нужно определить эту структуру данных. Назовем ее ValidationErrorResponse и она содержит список объектов Violation :
Затем создадим глобальный ControllerAdvice , который обрабатывает все ConstraintViolationExventions , которые пробрасываются до уровня контроллера. Чтобы отлавливать ошибки валидации и для тел запросов, мы также будем работать с MethodArgumentNotValidExceptions :
Здесь информацию о нарушениях из исключений переводится в нашу структуру данных ValidationErrorResponse .
Обратите внимание на аннотацию @ControllerAdvice , которая делает методы обработки исключений глобально доступными для всех контроллеров в контексте приложения.
Источник