我想使用Java验证程序来验证简单的帐户数据。帐户数据字段都不能为空,因此所有注释都为@NotNull。但是我仍然必须检查提供的密码及其重复次数是否相等。这迫使我通过检查null相等性来避免NullPointerException。请查看代码(为简洁起见,我省略了Maven依赖,因为依赖关系和正确的库不会引起问题):
AccountData类:
@ValidPassword
class AccountData {
@NotNull
public String login;
@NotNull
public String password;
@NotNull
public String repeatedPassword;
@NotNull
public String emailAddress;
@NotNull
public String countryName;
}
ValidCountry接口:
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = CountryValidatorImplementation.class)
@Documented
@interface ValidPassword {
String message() default "Passwords don't match";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
PasswordValidatorImplementation(在单独的.java文件中):
public class CountryValidatorImplementation implements
PasswordValidator<ValidPassword, Object> {
public PasswordValidatorImplementation() {
}
public boolean isValid(Object value, ConstraintValidatorContext context) {
AccountData accountData = (AccountData) value;
if(!accountData.password.equals(accountData.password)) {
return false;
}
//Not checking if account with login already exists in a DB for
//brevity
return true;
}
}
主要方法中的用法:
在我第一次设置密码并以编程方式重复Password时,不会导致NullPointerException:
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
AccountData accountData = new AccountData();
accountData.password = "1234";
accountData.repeatedPassword = "5678";
Set<ConstraintViolation<AccountData>> constraintViolationSet =
validator.validate(accountData);
导致NullPointerException,因为我对其执行验证的密码为空:
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
AccountData accountData = new AccountData();
Set<ConstraintViolation<AccountData>> constraintViolationSet =
validator.validate(accountData);
由于这些注释,是否有可能在字段上执行@NotNull指示的验证并为isValid返回false(甚至更早引发Exception),以便检查是否不再需要任何AccountData字段? *也欢迎与弹簧相关的解决方案!
答案 0 :(得分:0)
否,您不能及早停止验证。每个注释都会被处理,因此所有问题都可以一起报告。这比强迫用户反复尝试解决每个问题要好得多。
实际上,您应该编写几乎所有的自定义验证器,以将null
视为有效。然后它们会更加有用,可以根据需要与@NotNull
组合使用。
public boolean isValid(Object value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
// ...
由于验证器处理的字段值也可能为null,因此您可能需要这样的内容。
public class PasswordValidatorImpl implements PasswordValidator<ValidPassword, AccountData> {
public boolean isValid(AccountData value, ConstraintValidatorContext context) {
return value == null || Objects.equals(value.password, value.repeatedPassword);
}
}