For normal validation you can annotate your class with the annotations from the javax.validation.constraints
package, like javax.validation.constraints.NotEmpty
. For custom validation, you can make your own annotation that will call a custom validator that you write.
For example, if you wanted to create a validator that makes sure a field is nine characters long you could do the following:
First, create your custom validation annotation.
@Documented
@Constraint(validatedBy = NineCharactersValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface NineCharactersOnly {
String message() default "This field must contain exactly nine characters";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Next, create your custom validator:
public class NineCharactersValidator implements ConstraintValidator<NineCharactersOnly, String> {
@Override
public void initialize(NineCharactersOnly contactNumber) {
}
@Override
public boolean isValid(String contactField, ConstraintValidatorContext cxt) {
return contactField != null && contactField.length() == 9;
}
}
Next, use the annotation on fields that need to be constrained on your pojo.
public class ExampleClass {
@NineCharactersOnly
private String fieldThatMustBeNineCharacters;
}
Next, mark your method parameters in the controller with @Valid so they will be validated by Spring:
@RestController
public class CustomValidationController {
@PostMapping("/customValidationPost")
public ResponseEntity<String> customValidation(@Valid ExampleClass exampleClass, BindingResult result, Model m) {
// we know the data is valid if we get this far because Spring automatically validates the input and
// throws a MethodArgumentNotValidException if it's invalid and returns an HTTP response of 400 (Bad Request).
return ResponseEntity.ok("Data is valid");
}
}
Finally, if you want custom logic for handling validation errors instead of just sending a 400, you can create a custom validation handler method.
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> handleValidationException(MethodArgumentNotValidException e) {
Map<String, String> errors = new HashMap<>();
d.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
return errors;
}