spring 未调用Sping Boot 应用程序中的自定义约束验证器

c90pui9n  于 9个月前  发布在  Spring
关注(0)|答案(1)|浏览(81)

我正在尝试为我定义的一些类创建自定义验证器,如下所示(根据不同的示例,例如从here

@Target({ TYPE, ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = { MyClassValidator.class })
@Documented
public @interface MyClassValid {
    String message() default "The password2 does not comply with the rules";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

然后创建相应的validator:

public class MyClassValidator implements ConstraintValidator<MyClassValid, ChangePasswordBody> {
        @Override
        public boolean isValid(ChangePasswordBody value, ConstraintValidatorContext context) {
            
/*This check only for sample . Ot can be replaced by other logic*/
if (value.getNewPassword().length() > 2 ) {
                return true;
            }
            return false;
        }
    }

要验证的类:

@MyClassValid
public class ChangePasswordBody {
    private String oldPassword;
    private String newPassword;

    public String getOldPassword() {
        return oldPassword;
    }

    public void setOldPassword(String oldPassword) {
        this.oldPassword = oldPassword;
    }

    public String getNewPassword() {
        return newPassword;
    }
    
    public void setNewPassword(String newPassword) {
        this.newPassword = newPassword;
    }
}

这是使用ChangePasswordBody的代码

private static void testChangePwd(ApplicationContext applicationContext) {
    //...
    ChangePasswordBody pwdBody = new ChangePasswordBody();
    isValidPassword(pwdBody);
    //...
}
private static void isValidPassword(ChangePasswordBody pwdBody) {
    pwdBody.setNewPassword("l"); 
}

我看到在执行testChangePwd方法时- MyClassValidator.isValid没有被调用。代码中是否有遗漏/错误?Thanks in advance

vhipe2zx

vhipe2zx1#

验证不会自动发生,您必须以某种方式使用bean验证API调用它(例如Validator
假设spring-boot已经自动配置了Validator,在您的情况下,您可以通过以下方式触发验证:

private static void testChangePwd(ApplicationContext applicationContext) {
    
    ChangePasswordBody pwdBody = new ChangePasswordBody();
    pwdBody.setNewPassword("l");  

    Validator validator = applicationContext.getBean(Validator.class);
    Set<ConstraintViolation<ChangePasswordBody>> validationErrors =  validator.validate(pwdBody);

    //handle the validationErrors here...
}

但是它要求从业务代码中的spring上下文获取bean是一个非常糟糕的想法,因为它会将其耦合到spring。更好的方法是将要验证的对象作为方法参数,并通过执行该方法来验证它。
Something like:

@Validated
public class PasswordService {

    public void changePassword(@Valid ChangePasswordBody request) {

    }
}

如果ChangePasswordBody验证失败,它将抛出ConstraintViolationException

相关问题