验证复杂对象

时间:2016-04-15 21:45:34

标签: java validation hibernate-validator

关于hibernate验证器的新手问题。我有2个类,它们引用了另一个子类,并且取决于子类的父类验证应该更改。查看文档似乎我应该使用SequenceProvider,因此我为每个父类创建序列提供程序,而不是为子类包含适当的验证,但它似乎无法工作。

所以这是我的问题 - 1)这是正确的方法吗?或者我应该使用别的东西 2)如果这是正确的方法,我会错过什么

UserCreate类 -

Code:
@GroupSequenceProvider(CreateUserGroupSequenceProvider.class)
public class CreateUserRequest {
    @Valid
    @NotNull
    protected IdentityRequest identity;

    @Valid
    protected RegistrationProfileRequest registrationProfile;

    @Valid
    protected ProfileRequest profile;
}

UserUpdate类 -

@GroupSequenceProvider(UpdateUserGroupSequenceProvider.class)
public class UpdateUserRequest {

    @Valid
    protected IdentityRequest identity;

    @Valid
    protected RegistrationProfileRequest registrationProfile;

    @Valid
    protected ProfileRequest profile;
}

以下是子类ex:IdentityRequest -

public class IdentityRequest {

    @NotNull(groups = CreateIdentityValidation.class, message = "Invalid email")
    @Email(regexp = "(.+@[a-zA-Z0-9-.]+\\.[a-zA-Z0-9-.]+)", groups = {CreateIdentityValidation.class, EmailValidation.class}, message = "Invalid email")
    @SafeHtml(whitelistType = NONE, groups = {CreateIdentityValidation.class, EmailValidation.class}, message = "Invalid email")
    private String email;

    @NotNull(groups = {CreateIdentityValidation.class, PasswordValidation.class}, message = "Invalid password")
    @Size(min = 8, max = 255, groups = {CreateIdentityValidation.class, PasswordValidation.class}, message = "Invalid password")
    private String password;
}

所以我为每个创建和更新请求创建了2个序列提供者1。而且在每次验证的IdentityRequest中,我已经分配了组。

例如:当Parent = CreateRequest而不是电子邮件和密码时,两者都是必需的,而当UpdateRequest是可选的。

CreateUserGroupSequenceProvider

public class CreateUserGroupSequenceProvider implements DefaultGroupSequenceProvider<CreateUserRequest> {

    @Override
    public List<Class<?>> getValidationGroups(CreateUserRequest createUserRequest) {
        List<Class<?>> defaultGroupSequence = new ArrayList();
        defaultGroupSequence.add(createUserRequest.class);

        if (createUserRequest != null) {
            addIdentityValidationGroups(defaultGroupSequence, createUserRequest.getIdentity());

            addRegistrationProfileValidationGroups(defaultGroupSequence, createUserRequest.getRegistrationProfile());

            addProfileValidationGroups(defaultGroupSequence, createUserRequest.getProfile());
        }

        return defaultGroupSequence;
    }

    @Override
    protected void addIdentityValidationGroups(List<Class<?>> defaultGroupSequence, IdentityRequest identityRequest) {
        //validation group for username/password
        defaultGroupSequence.add(CreateIdentityValidation.class);
    }
}

UpdateUserGroupSequenceProvider

public class UpdateUserGroupSequenceProvider implements DefaultGroupSequenceProvider<UpdateUserRequest> {

    @Override
    public List<Class<?>> getValidationGroups(UpdateUserRequest updateUserRequest) {
        List<Class<?>> defaultGroupSequence = new ArrayList();
        defaultGroupSequence.add(UpdateUserRequest.class);

        if (updateUserRequest != null) {
            addIdentityValidationGroups(defaultGroupSequence, updateUserRequest.getIdentity());

            addRegistrationProfileValidationGroups(defaultGroupSequence, updateUserRequest.getRegistrationProfile());

            addProfileValidationGroups(defaultGroupSequence, updateUserRequest.getProfile());
        }

        return defaultGroupSequence;
    }

    @Override
    protected void addIdentityValidationGroups(List<Class<?>> defaultGroupSequence, IdentityRequest identityRequest) {
        if (identityRequest != null) {
            //Add password validation
            if (identityRequest.getPassword() != null) {
                defaultGroupSequence.add(IdentityValidation.PasswordValidation.class);
            }
            //Add email validation
            if (identityRequest.getEmail() != null) {
                defaultGroupSequence.add(IdentityValidation.EmailValidation.class);
            }
        }
    }
}

非常感谢任何帮助。即使经过大量调试后我还不清楚如何继续前进,它似乎跳过了UpdateRequest的电子邮件/密码验证,并将其缩小到Class和代码片段之下 -

Hibernate Validator Version = 5.2.2.Final ValidatorImpl.java:Line 1504

if ( !metaConstraint.getGroupList().contains( valueContext.getCurrentGroup() ) ) {
         return false;
      }

metaConstraint.getGroupList()= FirstNameValidation valueContext.getCurrentGroup()=默认

根据SequenceProvider文档,似乎所有验证都被添加到&#34;默认&#34;组。我假设我没有这样做。

如果我使用groupName = FirstNameValidation.class编写调用验证器的单元测试,而不是那些验证工作但是我使用的是spring-boot,我希望在这个对象上添加@Valid会触发那些验证。

1 个答案:

答案 0 :(得分:0)

我认为您的问题是,无论您是静态地还是通过GroupSequenceProvider重新定义默认组,默认组的重新定义都只是bean定义的本地化。 Bean验证规范说:

  

但请注意,默认组序列覆盖是本地的   它定义的类,不会传播到关联的类   对象。

检查规范的示例4.21 - http://beanvalidation.org/1.1/spec/