What You'll Learn

We want to ensure that acronyms remain unique across all charities. Therefore, whenever a form is submitted, we need to check that any new or amended acronym doesn't conflict with others.

This example is provided for illustration. There are a number of other options with custom validators. We are going to declare a validator that can be applied to fields or parameters. Declaring an interface for a custom validator can be done by following this template. All that needs to change is the message and the @Constraint which defines the class that actually checks the data.

@Constraint(validatedBy = UniqueFurlValidator.class)
@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface UniqueFurl {

    String message() default "The charities acronym must be unique";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

The work will be done by the UniqueFurlValidator class (next section).

In this example, we provide a naive (OK - I'll be honest, it's an oversight) implementation of the validation logic.

public class UniqueFurlValidator implements ConstraintValidator<UniqueFurl, String> {

    private CharitySearch charitySearch;

    public UniqueFurlValidator(CharitySearch aCharitySearch) {
        charitySearch = aCharitySearch;
    }

    @Override
    public boolean isValid(String acronym, ConstraintValidatorContext constraintValidatorContext) {
        return !charitySearch.doesCharityAcronymExist(acronym);
    }
}

The class implements a required interface that takes the annotation and the type of field being validated as types.

It injects a CharitySearch object and then implements the required isValid() method. To do this, we add a method to the CharitySearch interface and implementation that checks whether the acronym already exists.

Add a new charity but provide an existing acronym. The validation should prevent you from adding that charity.

To find the bug, edit an existing charity and try to save it.

We've added a custom validator. There are examples online of validators that can test multiple fields (e.g. are both password fields the same?)