5.2.13.2. Запуск валидации
- Валидация в UI
-
Компоненты Generic UI, соединенные с источником данных, получают экземпляр
BeanValidator
для проверки значения. Валидатор вызывается из методаComponent.Validatable.validate()
, реализуемого компонентом, и может выбрасывать исключениеCompositeValidationException
, содержащее набор объектов нарушений.Стандартный валидатор может быть программно удален или проинициализирован другой группой ограничений:
public class Screen extends AbstractWindow { @Inject private TextField field1; @Inject private TextField field2; public void init(Map<String, Object> params) { // Completely remove bean validation from the UI component field1.getValidators().stream() .filter(validator -> validator instanceof BeanValidator) .forEach(textField::removeValidator); // Here validators will check only constraints with explicitly set UiComponentChecks group, because // the Default group will not be passed field2.getValidators().stream() .filter(validator -> validator instanceof BeanValidator) .forEach(validator -> { ((BeanValidator) validator).setValidationGroups(new Class[] {UiComponentChecks.class}); }); } }
По умолчанию,
BeanValidator
содержит две группы:Default
иUiComponentChecks
.Если атрибут сущности аннотирован
@NotNull
без группы ограничений, он будет помечен как обязательный в метаданных, и UI-компоненты работающие с данным атрибутом через источник данных, будут иметь свойствоrequired = true
.Компоненты DateField и DatePicker автоматически устанавливают свои свойства
rangeStart
иrangeEnd
в соответствии с аннотациями@Past
и@Future
, не учитывая текущее время.Экраны редактирования выполняют валидацию ограничений уровня класса при коммите, если ограничения включают группу
UiCrossFieldChecks
и все проверки ограничений уровня атрибутов прошли успешно. Валидацию данного типа можно отключить с помощью свойства экранаcrossFieldValidate
в XML-дескрипторе или в контроллере:<window xmlns="http://schemas.haulmont.com/cuba/window.xsd" caption="msg://editorCaption" class="com.company.demo.web.task.TaskEdit" datasource="taskDs" crossFieldValidate="false"> <!-- ... --> </window>
public class TaskEdit extends AbstractEditor<Task> { @Override public void init(Map<String, Object> params) { setCrossFieldValidate(false); } }
- Валидация сервисов Middleware
-
Сервисы среднего слоя выполняют валидацию параметров и результатов методов, если метод имеет аннотацию
@Validated
в интерфейсе сервиса. Например:public interface TaskService { String NAME = "demo_TaskService"; @Validated @NotNull String completeTask(@Size(min = 5) String comment, @NotNull Task task); }
Аннотация
@Validated
может содержать указание групп ограничений для применения подмножества имеющихся ограничений. Если группы не указаны, то по умолчанию используются следующие:-
Default
иServiceParametersChecks
- для параметров методов -
Default
иServiceResultChecks
- для возвращаемых результатов методов
При возникновении ошибок валидации выбрасываются исключения
MethodParametersValidationException
иMethodResultValidationException
.При выполнении некоторой специфической программной валидации в сервисе, можно использовать исключение
CustomValidationException
для того, чтобы клиенты получали информацию об ошибках в том же формате что и от стандартной валидации. Это может быть особенно актуально для клиентов REST API. -
- Валидация в REST API
-
Универсальный REST API автоматически выполняет bean validation для действий создания и изменения сущностей. Ошибки валидации передаются клиенту следующим образом:
-
MethodResultValidationException
иValidationException
порождают HTTP статус500 Server error
-
MethodParametersValidationException
,ConstraintViolationException
иCustomValidationException
порождают HTTP статус400 Bad request
-
Тело ответа с
Content-Type: application/json
будет содержать список объектов со свойствамиmessage
,messageTemplate
,path
иinvalidValue
, например:[ { "message": "Invalid email: aaa", "messageTemplate": "{msg://com.company.demo.entity/Customer.email.validationMsg}", "path": "email", "invalidValue": "aaa" } ]
-
path
содержит путь к невалидному атрибуту в валидируемом графе объектов -
messageTemplate
содержит сторку, заданную в атрибутеmessage
аннотации -
message
содержит сообщение ошибки валидации -
invalidValue
возвращается только если тип значения один из следующих:String
,Date
,Number
,Enum
,UUID
.
-
-
- Программная валидация
-
Bean validation можно запустить программно используя интерфейс инфраструктуры
BeanValidation
, доступный и на middleware и на клиентском уровне. Через данный интерфейс необходимо получить реализациюjavax.validation.Validator
, которая и запускает валидацию. Результатом валидации является набор объектов типаConstraintViolation
. Например:@Inject private BeanValidation beanValidation; public void save(Foo foo) { Validator validator = beanValidation.getValidator(); Set<ConstraintViolation<Foo>> violations = validator.validate(foo); // ... }