【问题标题】:Validation for complex object复杂对象的验证
【发布时间】:2016-04-15 21:45:34
【问题描述】:

关于休眠验证器的新手问题。我有 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 个序列提供程序。而不是在 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 和 sn-p 以下 -

Hibernate 验证器版本 = 5.2.2.Final ValidatorImpl.java:第 1504 行

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

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

根据 SequenceProvider 文档,似乎所有验证都添加到“默认”组。我假设我这样做的方式不对。

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

【问题讨论】:

    标签: java validation hibernate-validator


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢@Hardy,那么我该如何处理这种验证呢?还是这不可能?
    • 也许您可以使用@ConvertGroup 并根据具体的用户请求类进行不同的组转换。
    猜你喜欢
    • 1970-01-01
    • 2013-01-31
    • 2023-03-13
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多