5.2.13.2. Running Validation
- Validation in UI
-
Generic UI components connected to a datasource get an instance of
BeanValidatorto check the field value. The validator is invoked from theComponent.Validatable.validate()method implemented by the visual component and can throw theCompositeValidationExceptionexception that contains the set of violations.The standard validator can be removed or initialized with a different constraint group:
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}); }); } }By default,
BeanValidatorhas bothDefaultandUiComponentChecksgroups.If an entity attribute is annotated with
@NotNullwithout constraint groups, it will be marked as mandatory in metadata and UI components working with this attribute through a datasource will haverequired = true.The DateField and DatePicker components automatically set their
rangeStartandrangeEndproperties by the@Pastand@Futureannotations, but without considering time.Editor screens perform validation against class-level constraints on commit if the constraint includes the
UiCrossFieldChecksgroup and if all attribute-level checks are passed. You can turn off the validation of this kind using thecrossFieldValidateproperty of the screen in the screen XML descriptor or in the controller:<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); } }
- Validation in Middleware Services
-
Middleware services perform validation of parameters and results if a method has annotation
@Validatedin the service interface. For example:public interface TaskService { String NAME = "demo_TaskService"; @Validated @NotNull String completeTask(@Size(min = 5) String comment, @NotNull Task task); }The
@Validatedannotation can specify constraint groups to apply a certain set of constraints. If no groups are specified, the following are used by default:-
DefaultandServiceParametersChecks- for method parameters -
DefaultandServiceResultChecks- for method return value
The
MethodParametersValidationExceptionandMethodResultValidationExceptionexceptions are thrown on validation errors.If you perform some custom programmatic validation in a service, use
CustomValidationExceptionto inform clients about validation errors in the same format as the standard bean validation does. It can be particularly relevant for REST API clients. -
- Validation in REST API
-
Universal REST API automatically performs bean validation for create and update actions. Validation errors are returned to the client in the following way:
-
MethodResultValidationExceptionandValidationExceptioncause500 Server errorHTTP status -
MethodParametersValidationException,ConstraintViolationExceptionandCustomValidationExceptioncause400 Bad requestHTTP status -
Response body with
Content-Type: application/jsonwill contain a list of objects withmessage,messageTemplate,pathandinvalidValueproperties, for example:[ { "message": "Invalid email: aaa", "messageTemplate": "{msg://com.company.demo.entity/Customer.email.validationMsg}", "path": "email", "invalidValue": "aaa" } ]-
pathindicates a path to the invalid attribute in the validated object graph -
messageTemplatecontains a string which is defined in themessageannotation attribute -
messagecontains an actual value of the validation message -
invalidValueis returned only if its type is one of the following:String,Date,Number,Enum,UUID.
-
-
- Programmatic Validation
-
You can perform bean validation programmatically using the
BeanValidationinfrastructure interface, available on both middleware and client tier. It is used to obtain ajavax.validation.Validatorimplementation which runs validation. The result of validation is a set ofConstraintViolationobjects. For example:@Inject private BeanValidation beanValidation; public void save(Foo foo) { Validator validator = beanValidation.getValidator(); Set<ConstraintViolation<Foo>> violations = validator.validate(foo); // ... }