如何在DAO中同时使用Spring Validation Annotation(Bean验证规范)

时间:2017-01-09 13:30:10

标签: java spring spring-boot bean-validation

我有一个用户实体,它使用Spring Validation Annotation [Edited - Bean Validation Specification]如下。

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

当我用于注册操作时,这个验证是可以的,但是我试图通过名为Update的不同Action使用相同的Entity(User),我想使@NotEmpty Annotation无效。我怎么能这样做?

问候。

2 个答案:

答案 0 :(得分:3)

  

我有一个用户实体,它使用的是Spring Validation Annotation,如下所示。

首先,它不是“Spring Validation Annotation”。这些是来自Bean Validation Specification的注释(称为JSR-303和JSR-349)。某些注释是非标准的,由验证提供程序提供(例如,Hibernate Validator)。

  

但是我试图通过名为Update的不同Action使用相同的Entity(User),我想使@NotEmpty Annotation无效

可以通过使用注释的groups属性来实现。在第一个场景中,您将运行所有组,而在另一个场景中只运行其中一些组。不幸的是,规范(目前)不支持(因为@Valid不允许提供groups)。

这是Spring的非标准注释@Validated拯救的地方:你可以用它指定验证组!

但它仅适用于控制器中的验证模型。在将实体持久保存到数据库之前,它不能用作验证,因为无法指定组(Default组始终使用)。

例如,您可以使用此问题:Hibernate-validator Groups with Spring MVC

答案 1 :(得分:0)

您可以从域模型中的用户实体中删除验证,然后将其移至服务层。这更有意义,因为实体的验证取决于上下文。

在您的示例中,有两个用例:

  • 用户应该可以注册

  • 用户应该能够更改他的数据,例如他的密码。

然后可以像下面的代码一样建模。

 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;

    }

}

这当然只是一个例子,因为我不知道你的代码的其余部分是如何实现的。