Вопрос: Как сделать валидацию данных?

Лучший ответ:
Я на практике использую следующий подход: для каждой хранимой сущности, которую может создать/изменить пользователь, я создаю класс, описывающий форму (иногда бывает, что для редактирования и создания используются даже разные классы в виду разного набора полей). 
Это делается по двум причинам: во-первых - не все поля в хранимой сущности пользователи могут создавать/изменять (например, даты создания/редактирования и идентификаторы), во-вторых - вынесение аннотаций валидации из класса сущности.
Теперь ближе к делу: для валидации существуют аннотации из пакета javax.validation.constraints, а также дополнительные, предоставляемые реализациями Bean Validation API (например @Email из Hibernate Validator).
Допустим, у нас есть класс, представляющий собой форму регистрации:SignUpForm.javapublic class SignUpForm {
    @Email
    private String email;

    @Size(min = 8)
    @Pattern(regexp = "какая-нибудь регулярка для проверки надёжности пароля")
    private String password;
}
В контроллере мы будем принимать форму таким образом:SignUpController.javapublic class SignUpController {
    public ResponseEntity signUp(@RequestBody @Valid SignUpForm form, BindingResult bindingResult) {
    }
}
В form будут содержаться данные, отправленные пользователем, а в bindingResult - результат валидации, который можно легко проверить, вызвав bindingResult.hasErrors(). Отмечу только то, что аргумент класса BindingResult должен быть сразу после аргумента, помеченного аннотациями @RequestBody и valid, в других случаях валидация работать не будет.
Но дальше - больше. Допустим, нам нужно добавить поле для подтверждения пароля и проверять его соответствие паролю. В таком случае нам надо добавить свою аннотацию (в данном случае на класс) и валидатор. 
Новый класс формы:SignUpForm.java@PasswordMatch
public class SignUpForm {
    @Email
    private String email;

    @Size(min = 8)
    @Pattern(regexp = "какая-нибудь регулярка для проверки надёжности пароля")
    private String password;

    private String passwordConfirmation;
}
Аннотация:PasswordMatch.java@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = PasswordMatchValidator.class)
@Documented
public @interface PasswordMatch {

    String message() default "{constraints.passwordmatch}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Target({TYPE, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Documented
    @interface List {

        PasswordMatch[] value();
    }
}
Ну и валидатор:PasswordMatchValidator.javapublic class PasswordMatchValidator implements ConstraintValidator<PasswordMatch, SignUpForm> {

    @Override
    public void initialize(PasswordMatch constraintAnnotation) {
    }

    @Override
    public boolean isValid(SignUpForm value, ConstraintValidatorContext context) {
            return Objects.equals(value.getPassword(), value.getPasswordConfirmation());
    }
}
И ещё один способ валидации - при помощи спринговых валидаторов. Допустим, нам нужно проверить существование указанного email в нашей БД, что вполне вписывается в процесс валидации. В таком случае пишем валидатор:SignUpFormValidator.javapublic class SignUpFormValidator implements Validator {
    public boolean supports(Class<?> type) {
        return SignUpForm.class.isAssignableFrom(type);
    }
    public void validate(Object target, Errors errors) {
        SignUpForm form = (SignUpForm) target;
        // проверяем, что нужно и добавляем ошибки в errors, если они есть
    }
}
Регистрируем его в контроллере:SignUpController.javapublic class SignupController {
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.addValidators(new SignUpFormValidator());
    }
}
После этого Spring будет производить дополнительную валидацию при помощи этого валидатора.
Более подробно с валидацией в Spring можно почитать в официальной документации.

Худший ответ:
Я вижу 2 способа:
1. Подключите form validating
2. У вас скорее всего есть класс для описания реквеста. добавте там метод  validate и вызовите его в начале контроллераpublic class AuthenticateRequestBody {

    private String username;

    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(final String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(final String password) {
        this.password = password;
    }

    public void validate() {
        if (StringUtils.isBlank(username)) {
            throw new ValidationException("Username is absent!");
        } else if (StringUtils.isBlank(password)) {
            throw new ValidationException("Password is absent!");
        }
    }
}@PostMapping("/authenticate")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    void authenticate(@RequestBody final AuthenticateRequestBody request) {
        request.validate();

        authenticationService.authenticate(request.getUsername(), request.getPassword());
    }