4.2.13.2. Running Validation
- Validation in UI
-
Generic UI components connected to a datasource get an instance of
BeanValidator
to check the field value. The validator is invoked from theComponent.Validatable.validate()
method implemented by the visual component and can throw theCompositeValidationException
exception 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,
BeanValidator
has bothDefault
andUiComponentChecks
groups.If an entity attribute is annotated with
@NotNull
without 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
rangeStart
andrangeEnd
properties by the@Past
and@Future
annotations, but without considering time.Editor screens perform validation against class-level constraints on commit if the constraint includes the
UiCrossFieldChecks
group and if all attribute-level checks are passed. You can turn off the validation of this kind using thecrossFieldValidate
property 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
@Validated
in 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
@Validated
annotation can specify constraint groups to apply a certain set of constraints. If no groups are specified, the following are used by default:-
Default
andServiceParametersChecks
- for method parameters -
Default
andServiceResultChecks
- for method return value
The
MethodParametersValidationException
andMethodResultValidationException
exceptions are thrown on validation errors.If you perform some custom programmatic validation in a service, use
CustomValidationException
to 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:
-
MethodResultValidationException
andValidationException
cause500 Server error
HTTP status -
MethodParametersValidationException
,ConstraintViolationException
andCustomValidationException
cause400 Bad request
HTTP status -
Response body with
Content-Type: application/json
will contain a list of objects withmessage
,messageTemplate
,path
andinvalidValue
properties, for example:[ { "message": "Invalid email: aaa", "messageTemplate": "{msg://com.company.demo.entity/Customer.email.validationMsg}", "path": "email", "invalidValue": "aaa" } ]
-
path
indicates a path to the invalid attribute in the validated object graph -
messageTemplate
contains a string which is defined in themessage
annotation attribute -
message
contains an actual value of the validation message -
invalidValue
is 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
BeanValidation
infrastructure interface, available on both middleware and client tier. It is used to obtain ajavax.validation.Validator
implementation which runs validation. The result of validation is a set ofConstraintViolation
objects. For example:@Inject private BeanValidation beanValidation; public void save(Foo foo) { Validator validator = beanValidation.getValidator(); Set<ConstraintViolation<Foo>> violations = validator.validate(foo); // ... }