Различные аннотации проверки Hibernate для одного и того же свойства

Я использую две аннотации проверки свойства в компоненте:

@NotEmpty(message = "{name.required}")
@Pattern(regex = "^([A-Za-z0-9]{2,}(\\-[a-zA-Z0-9])?)$", message = "{invalid.name}")
private String name;

Если я оставил имя пустым, я получил две ошибки, но мне нужно только первое сообщение об ошибке (если возникает первое условие, покажите его сообщение об ошибке, а затем пропустите второе условие).


person Mahmoud Saleh    schedule 13.10.2010    source источник


Ответы (2)


если возникает первое условие, покажите его сообщение об ошибке, затем пропустите второе условие

Это можно сделать, создав Composite Constraint и аннотировав его метаограничением @ReportAsSingleViolation.

имя_пользователя.java

@ReportAsSingleViolation
@NotEmpty
@Pattern(regexp="^([A-Za-z0-9]{2,}(\\-[a-zA-Z0-9])?)$")
@Constraint(validatedBy = {})
public @interface UserName {
    String message() default "invalid userName!";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Ссылка 3.2. Состав ограничений

person dira    schedule 23.11.2010
comment
Игнорируется ли порядок этих аннотаций @NotEmpty и @Pattern? Также они запускаются перед пользовательским ограничением? - person Stephane; 06.11.2015

Принятый ответ не работает, как вы ожидаете. Конечно, композиция ограничений хороша, только если вы хотите перечислить ВСЕ ошибки в ВСЕЙ цепочке композиции. Это не работает, если вы хотите досрочно выйти из первой ошибки проверки.

В документах для @ReportAsSingleViolation говорится, что отчеты об ошибках каждого отдельного ограничения композиции игнорируются.

Использование примера принятия

@ReportAsSingleViolation
@NotEmpty
@Pattern(regexp="^([A-Za-z0-9]{2,}(\\-[a-zA-Z0-9])?)$")
@Constraint(validatedBy = {})
public @interface UserName {
    String message() default "invalid userName!";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Это означает, что вы получите сообщение об ошибке по умолчанию для аннотации UserName, которое является «invalid userName!» даже если @NotEmpty сначала выйдет из строя....

Я должен сказать, что я весьма шокирован тем, насколько плох этот дизайн разработчиками проверки java bean. Нет абсолютно никакого смысла составлять валидации, если вы возвращаете совершенно не относящееся к делу сообщение. Сначала он должен завершиться ошибкой И вернуть соответствующую ошибку для проверки, которая на самом деле не удалась!. В любом случае, без массивных уродливых хаков это сделать невозможно. Такая простая задача проверки превращается в кошмар. 0_о

Мое обходное решение - не сочинять валидации, просто создайте 1 валидацию и реализуйте все это самостоятельно. Это не СУХОЕ, но, по крайней мере, простое.

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordValidator.class)
public @interface Password {
    String message() default "{com.example.Password.message}";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}



public class PasswordValidator implements ConstraintValidator<Password, String> {
    private Pattern twoDigitsPattern;

    public void initialize(Password constraint) {
        twoDigitsPattern = Pattern.compile("(.*[\\d]){2}");
    }

    public boolean isValid(String password, ConstraintValidatorContext context) {
        context.disableDefaultConstraintViolation();

        if (password == null) {
            context.buildConstraintViolationWithTemplate("{javax.validation.constraints.NotNull.message}")
                    .addConstraintViolation();
            return false;
        }

        if (password.length() < 5 || password.length() > 10) {
            context.buildConstraintViolationWithTemplate("must be between 5 to 10 characters")
                    .addConstraintViolation();
            return false;
        }

        if (!twoDigitsPattern.matcher(password).matches()) {
            context.buildConstraintViolationWithTemplate("must contain 2 digits between [0-9]").addConstraintViolation();
            return false;
        }

        return true;
    }

}

person reversebind    schedule 10.11.2017