3.2.13.2. Запуск валидации
- Валидация в UI
-
Компоненты Generic UI, соединенные с источником данных, получают экземпляр
BeanValidator
для проверки значения. Валидатор вызывается из методаComponent.Validatable.validate()
, реализуемого компонентом, и может выбрасывать исключениеCompositeValidationException
, содержащее набор объектов нарушений.Стандартный валидатор может быть программно удален или проинициализирован другой группой ограничений:
@UiController("sample_NewScreen") @UiDescriptor("new-screen.xml") public class NewScreen extends Screen { @Inject private TextField<String> field1; @Inject private TextField<String> field2; @Subscribe protected void onInit(InitEvent event) { field1.getValidators().stream() .filter(BeanPropertyValidator.class::isInstance) .forEach(field1::removeValidator); (1) field2.getValidators().stream() .filter(BeanPropertyValidator.class::isInstance) .forEach(validator -> { ((BeanPropertyValidator) validator).setValidationGroups(new Class[] {UiComponentChecks.class}); (2) }); } }
1 Полностью удаляем валидацию с компонента. 2 Здесь валидаторы будут проверять только ограничения, явно установленные группой UiComponentChecks, так как группа по умолчанию не передаётся. По умолчанию,
BeanValidator
содержит две группы:Default
иUiComponentChecks
.Если атрибут сущности аннотирован
@NotNull
без группы ограничений, он будет помечен как обязательный в метаданных, и UI-компоненты работающие с данным атрибутом через источник данных, будут иметь свойствоrequired = true
.Компоненты DateField и DatePicker автоматически устанавливают свои свойства
rangeStart
иrangeEnd
в соответствии с аннотациями@Past
,@PastOrPresent
,@Future
,@FutureOrPresent
.Экраны редактирования выполняют валидацию ограничений уровня класса при коммите, если ограничения включают группу
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 StandardEditor<Task> { @Subscribe protected void onInit(InitEvent event) { setCrossFieldValidate(false); } }
- Валидация в DataManager
-
DataManager может выполнять валидацию сохраняемых сущностей. Следующие параметры оказывают влияние на валидацию:
-
Свойство приложения cuba.dataManagerBeanValidation устанавливает глобальный признак, выполнять ли валидацию по умолчанию.
-
Глобальный признак можно переопределить, устанавливая значение типа
CommitContext.ValidationMode
вCommitContext
при выполненииDataManager.commit()
, или вDataContext.PreCommitEvent
при сохранении данных в экране UI. -
В
CommitContext
и вDataContext.PreCommitEvent
можно передать список групп валидации для применения некоторого подмножества определенных ограничений.
-
- Валидация сервисов 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); // ... }