I am using spring to validate a form. The model for the form is similar to this:
public class FormModel {
@NotBlank
private String name;
@NotNull
@ImageSizeConstraint
private MultipartFile image;
}
The '@ImageSizeConstraint' is a custom constraint. What I want is for the @NotNull to be evaluated first and if this evaluates to false, not to evaluate @ImageSizeConstraint.
If this is not possible, I will have to check for null in the custom constraint as well. Which is not a problem, but I would like to seperate the concerns (not null / image size / image / aspectratio / etc).
Naturally, we're going with a simple validation rule here in order to show how the validator works. ConstraintValidator defines the logic to validate a given constraint for a given object. Implementations must comply with the following restrictions:
Overview Generally, when we need to validate user input, Spring MVC offers standard predefined validators. However, when we need to validate a more particular type of input, we have the ability to create our own custom validation logic.
The Bean Validation API is the popular approach for data validations in Spring applications. Here we will be using the hibernate implementation of the Bean Validation API known as Hibernate Validator.
The Spring MVC framework provides us with standard predefined validators to validate user input data in a simple and straightforward way. The Bean Validation API is the popular approach for data validations in Spring applications.
You may use constraints grouping and group sequences to define the validation order. According to JSR-303 (part 3.5. Validation routine):
Unless ordered by group sequences, groups can be validated in no particular order. This implies that the validation routine can be run for several groups in the same pass.
As Hibernate Validator documentation says:
In order to implement such a validation order you just need to define an interface and annotate it with @GroupSequence, defining the order in which the groups have to be validated (see Defining a group sequence). If at least one constraint fails in a sequenced group, none of the constraints of the following groups in the sequence get validated.
First, you have to define constraint groups and apply them to the constraints:
public interface CheckItFirst {}
public interface ThenCheckIt {}
public class FormModel {
@NotBlank
private String name;
@NotNull(groups = CheckItFirst.class)
@ImageSizeConstraint(groups = ThenCheckIt.class)
private MultipartFile image;
}
And then, as constraints are evaluated in no particular order, regardless of which groups they belong to (Default
group too), you have to create @GroupSequence for your image
field constraints groups.
@GroupSequence({ CheckItFirst.class, ThenCheckIt.class })
public interface OrderedChecks {}
You can test it with
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<FormModel>> constraintViolations =
validator.validate(formModel, OrderedChecks.class);
To apply this validation in Spring MVC Controller methods, you may use the @Validated annotation, which can specify the validation groups for method-level validation:
@PostMapping(value = "/processFormModel")
public String processFormModel(@Validated(OrderedChecks.class) FormModel formModel) {
<...>
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With