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;
}