首页 > 解决方案 > Spring Boot 验证 - 一个从两个不为空

问题描述

我正在尝试验证 Spring Boot 中两个字段之一是否不为空?

我在主对象的方法类中设置了它:

@NotNull(message = "Username field is required")
private String username;

@NotNull(message = "Email field is required")
private String email;

但这需要两个字段都不为空。然后我使用此处描述的自定义验证https://lmonkiewicz.com/programming/get-noticed-2017/spring-boot-rest-request-validation/但我无法让该示例正常工作。我必须坚持

用户类声明:

@CombinedNotNull(fields = {"username","email"})
public class User implements {

    private long id = 0L;
    @NotNull(message = "First name field is required")
    private String firstName;

    @NotNull(message = "Last name field is required")
    private String lastName;

    private String username;
    private String email;

    @NotNull(message = "Status field is required")
    private String status;

    ...all methods here...
    ...setters and getters...

}

CombibnedNotNull 类:

@Documented
@Retention(RUNTIME)
@Target({ TYPE, ANNOTATION_TYPE })
@Constraint(validatedBy = userValidator.class)
public @interface CombinedNotNull {
        String message() default "username or email is required";
        Class<?>[] groups() default { };
        Class<? extends Payload>[] payload() default { };
}

用户验证器类:

@Component
public class userValidator implements ConstraintValidator<CombinedNotNull, User> {

    @Override
    public void initialize(final CombinedNotNull combinedNotNull) {
        fields = combinedNotNull.fields();
    }

    @Override
    public boolean isValid(final User user, final ConstraintValidatorContext context) {
        final BeanWrapperImpl beanWrapper = new BeanWrapperImpl(user);

        for (final String f : fields) {
            final Object fieldValue = beanWrapper.getPropertyValue(f);

            if (fieldValue == null) {
                return false;
            }
        }

        return true;
    }
}

有没有其他方法可以完成这项工作,或者我应该使用该页面中的“复杂”示例?

标签: javavalidationspring-boot

解决方案


我假设username OR email不能为空。不是异或

在类中添加这个 getter User

@AssertTrue(message = "username or email is required")
private boolean isUsernameOrEmailExists() {
    return username != null || email != null;
}

根据我的经验,方法名称必须遵循 getter 名称约定,否则这将不起作用。例如,getFooisBar

这有一个小问题:此验证错误的字段名称将是usernameOrEmailExists,只有 1 个错误字段。如果这不是问题,这可能会有所帮助。


但是,如果您想在发生错误时拥有usernameemail字段,则可以使用此解决方法:

public String getUsername() {
    return username;
}

public String getEmail() {
    return email;
}

@AssertTrue(message = "username or email is required")
private boolean isUsername() {
    return isUsernameOrEmailExists();
}

@AssertTrue(message = "username or email is required")
private boolean isEmail() {
    return isUsernameOrEmailExists();
}

private boolean isUsernameOrEmailExists() {
    return username != null || email != null;
}

get...方法只是一般用途的简单吸气剂,is... 用于验证。这将发出 2 个带有usernameemail字段的验证错误。


推荐阅读