Как использовать аннотацию Spring Validation в DAO одновременно (спецификация Bean Validation)

У меня есть пользовательский объект, и он использует аннотацию Spring Validation[Edited - Bean Validation Specification] следующим образом.

@NotEmpty(message = "{warn.null.user.password}")
private String            password;

Эта проверка в порядке, когда я использую для действия регистрации, но я пытался использовать один и тот же объект (пользователь) с другим действием, называемым обновлением, и я хочу аннулировать аннотацию @NotEmpty. Как я могу это сделать?

С уважением.

2 ответа

Решение

У меня есть пользовательский объект, и он использует Spring Validation Annotation, как указано ниже.

Прежде всего, это не "Spring Validation Annotation". Это аннотации из спецификации проверки бинов (известной как JSR-303 и JSR-349). Некоторые аннотации нестандартны и поставляются провайдером валидации (например, Hibernate Validator).

Но я пытался использовать одну и ту же сущность (пользователя) в другом действии, называемом обновлением, и хочу аннулировать аннотацию @NotEmpty

Это может быть достигнуто с помощью groups атрибут аннотации. В первом сценарии вы будете запускать все группы, а в другом - только некоторые из них. К сожалению, Спецификация (в настоящее время) не поддерживает это (потому что @Valid не позволяет обеспечить groups).

Вот где нестандартная аннотация Spring @Validated на помощь приходит: с ним можно указать группы проверки!

Но это работает только для проверки моделей в контроллере. Он не работает как проверка перед сохранением сущности в базе данных, потому что нет способа указать группы (Default группа всегда используется).

В качестве примера вы можете использовать этот вопрос: Hibernate-validator Groups с Spring MVC

Вы можете удалить проверку из пользовательской сущности в вашей модели домена и переместить ее на уровень обслуживания. Это имеет больше смысла, потому что проверка сущности зависит от контекста.

В вашем примере есть 2 варианта использования:

  • пользователь должен иметь возможность зарегистрироваться

  • пользователь должен иметь возможность изменить свои данные, например, свой пароль.

Тогда это можно смоделировать, как в коде ниже.

 public class User {

        private final String email;
        private String password;

        public User(final String email, final String password) {

            this.email = email;
            this.password = password;
        }

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

        public String getEmail() {
            return email;
        }

        public String getPassword() {
            return password;
        }

    }

Это также имеет то преимущество, что модель вашего домена не зависит от внешней библиотеки.

Вы можете переместить проверки с уровня домена на уровень обслуживания, где проверка зависит от выполняемого действия. Есть команда регистрации и команда обновления.

Когда пользователь регистрируется, электронная почта и пароль не должны быть пустыми.

public class RegisterUserCommand {

    @NotEmpty(message = "{warn.null.user.email}")
    private String email;
    @NotEmpty(message = "{warn.null.user.password}")
    private String password;
    ...

Команда обновления требует только, чтобы адрес электронной почты не был пустым

public class UpdateUserCommand {

    @NotEmpty(message = "{warn.null.user.email}")
    private String email;
    private String password;
    ...

В слое обслуживания вы можете сделать что-то вроде:

public class UserService {

    private final UserDao userDao;

    public UserService(final UserDao userDao){
        this.userDao = userDao;
    }

    public User register(final RegisterUserCommand command) {
        User user = new User(command.getEmail(), command.getPassword());
        return userDao.save(user);
    }

    public User update(final UpdateUserCommand command) {
        User user = userDao.findUserByEmail(command.getEmail());
        user.changePassword(command.getPassword);
        return user;

    }

}

Это, конечно, только пример, потому что я не знаю, как реализована остальная часть вашего кода.

Другие вопросы по тегам