java / intermediate
Snippet
Enforcing Custom Domain Data Constraints with ConstraintValidator
Custom validation annotations in Spring leverage Jakarta Bean Validation alongside Spring's dependency injection. By annotating the ConstraintValidator implementation with @Component or letting Spring discover it, the validator can inject other beans and perform domain-specific input assertions directly on incoming request payloads and records.
snippet.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Target({ElementType.FIELD, ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy = IbanChecksumValidator.class)@Documentedpublic @interface ValidIban {String message() default "Invalid IBAN checksum structure";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};}@Componentpublic class IbanChecksumValidator implements ConstraintValidator<ValidIban, String> {@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {if (value == null || value.isBlank()) {return true;}String sanitized = value.replaceAll("\\s+", "");return sanitized.matches("^[A-Z]{2}\\d{2}[A-Z0-9]{1,30}$");}}public record TransferRequest(@ValidIban String destinationIban, BigDecimal amount) {}
spring
Breakdown
1
@Constraint(validatedBy = IbanChecksumValidator.class)
Binds the validation annotation to its concrete validation logic implementation class.
2
public class IbanChecksumValidator implements ConstraintValidator<ValidIban, String>
Implements validation checks for String fields annotated with the custom @ValidIban annotation.
3
public record TransferRequest(@ValidIban String destinationIban, BigDecimal amount) {}
Applies domain validation directly to record components, evaluated during @Valid controller binding.