Принятый ответ не работает, как вы ожидаете. Конечно, композиция ограничений хороша только в том случае, если вы хотите перечислить ALL ошибок в цепочке композиции ENTIRE . Он не работает, если вы хотите досрочно выйти из первой ошибки проверки.
Документы для @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
, которая является "недопустимым именем пользователя!" даже если @NotEmpty сначала потерпит неудачу ....
Должен сказать, что я весьма шокирован тем, насколько плохим этот проект реализаторы проверки Java-бина. Не имеет смысла составлять проверки, если вы возвращаете совершенно не относящееся к делу сообщение. Сначала он должен потерпеть неудачу И вернуть соответствующую ошибку для проверки, которая на самом деле не удалась! Во всяком случае, нет способа сделать это без массивных уродливых хаков. Такая простая задача проверки превращается в кошмар. 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;
}
}