我想使用 java validator 验证简单的帐户数据。帐户数据字段不能为空,因此所有字段都被注释为@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;
}
有效国家接口(interface):
@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;
}
}
主方法中的用法:
当我第一次以编程方式设置密码和重复密码时,不会导致 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(甚至更早抛出异常),以便检查是否不再需要任何 AccountData 字段? *也欢迎Spring相关解决方案!
最佳答案
不,您不能提前停止验证。每个注释都会被处理,因此所有问题都可以一起报告。这比用户轮流解决每个问题时强制重复试错要好得多。
事实上,您应该编写几乎所有自定义 validator 以将 null
视为有效。那么它们就更加有用,可以根据需要与 @NotNull
组合使用或不组合使用。
public boolean isValid(Object value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
// ...
当您的 validator 处理也可能为空的字段值时,您可能需要这样的东西。
public class PasswordValidatorImpl implements PasswordValidator<ValidPassword, AccountData> {
public boolean isValid(AccountData value, ConstraintValidatorContext context) {
return value == null || Objects.equals(value.password, value.repeatedPassword);
}
}
关于java - 验证字段时如何避免重复检查空值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56517049/