Hibernate validator: @Email принимает запрос @stackoverflow как действительный?
Я использую аннотацию @Email
для проверки адреса электронной почты.
Проблема, с которой я сталкиваюсь, заключается в том, что он принимает такие вещи, как [email protected]
, как действительный адрес электронной почты.
Я предполагаю, что это потому, что они хотят поддерживать адреса интрасети, но я не могу найти флаг, поэтому он проверяет расширение.
Мне действительно нужно переключиться на @Pattern
(и любые рекомендации по шаблону электронной почты, который является гибким), или я что-то не хватает?
Ответы
Ответ 1
Собственно, @Email
из Hibernate Validator использует regexp внутри. Вы можете легко определить свое собственное ограничение на основе этого регулярного выражения, измененного по мере необходимости (обратите внимание на +
в конце DOMAIN
):
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {})
@Pattern(regexp = Constants.PATTERN, flags = Pattern.Flag.CASE_INSENSITIVE)
public @interface EmailWithTld {
String message() default "Wrong email";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
interface Constants {
static final String ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~-]";
static final String DOMAIN = "(" + ATOM + "+(\\." + ATOM + "+)+";
static final String IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]";
static final String PATTERN =
"^" + ATOM + "+(\\." + ATOM + "+)*@"
+ DOMAIN
+ "|"
+ IP_DOMAIN
+ ")$";
}
Ответ 2
Вы также можете использовать
Ответ 3
Фактически проверка адресов электронной почты действительно сложна. Невозможно проверить, что адрес электронной почты синтаксически корректен и адресован предполагаемому получателю в аннотации. Аннотация @Email
- полезная минимальная проверка, которая не страдает от проблемы ложных негативов.
Следующим шагом в проверке должно быть отправление электронной почты с вызовом, который пользователь должен выполнить, чтобы установить, что пользователь имеет доступ к адресу электронной почты.
Лучше принять несколько ложных срабатываний на шаге 1 и разрешить некоторые недопустимые адреса электронной почты, чем отклонять действительных пользователей. Если вы хотите применить дополнительные правила, вы можете добавить дополнительные проверки, но будьте очень осторожны в отношении того, что вы считаете требованием действительного адреса электронной почты. Например, в RFC нет ничего, что диктует, что [email protected]
будет недействительным, поскольку nl
является зарегистрированным доменом верхнего уровня страны.
Ответ 4
Здесь валидатор электронной почты javax.validation с использованием Apache Commons Validator
public class CommonsEmailValidator implements ConstraintValidator<Email, String> {
private static final boolean ALLOW_LOCAL = false;
private EmailValidator realValidator = EmailValidator.getInstance(ALLOW_LOCAL);
@Override
public void initialize(Email email) {
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
if( s == null ) return true;
return realValidator.isValid(s);
}
}
И аннотация:
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {CommonsEmailValidator.class})
@Documented
@ReportAsSingleViolation
public @interface Email {
String message() default "{org.hibernate.validator.constraints.Email.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface List {
Email[] value();
}
}
Ответ 5
Очевидно, что я опаздываю к партии, тем не менее я отвечаю на этот вопрос,
Почему мы не используем аннотацию @Pattern с регулярными выражениями в нашем классе Validation вроде этого
public Class Sigunup {
@NotNull
@NotEmpty
@Pattern((regexp="[A-Za-z0-9._%-+][email protected][A-Za-z0-9.-]+\\.[A-Za-z]{2,4}")
private String email;
}
Это проще.
Ответ 6
Решение композиции ограничений не работает. Когда электронная почта используется совместно с шаблоном, регулярное выражение электронной почты удерживается в более высоком приоритете. Я считаю, что это связано с тем, что аннотация электронной почты переопределяет несколько атрибутов шаблона, а именно, флаги и регулярное выражение (здесь один ключ). Если я удалю @Email
, только регулярное выражение @Pattern
применится к проверке.
/**
* @return an additional regular expression the annotated string must match. The default is any string ('.*')
*/
@OverridesAttribute(constraint = Pattern.class, name = "regexp") String regexp() default ".*";
/**
* @return used in combination with {@link #regexp()} in order to specify a regular expression option
*/
@OverridesAttribute(constraint = Pattern.class, name = "flags") Pattern.Flag[] flags() default { };
Ответ 7
Если вы собираетесь попробовать описанное выше решение fooobar.com/questions/129148/..., добавьте @ReportAsSingleViolation
в определение аннотации, таким образом вы избежите как сообщения проверки (одно из @Email
, так и одно из @Pattern
), так как это составная аннотация:
@Email(message="Please provide a valid email address")
@Pattern(regexp="[email protected]+\\..+", message="Please provide a valid email address")
@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@Documented
@ReportAsSingleViolation
Из @interface ReportAsSingleViolation
javax.validation: validation-api: 1.1.0.Final) определение аннотации:
"... Оценка составленных ограничений останавливается на первой проверке ошибка в случае, если налагаемое ограничение аннотировано с помощью ReportAsSingleViolation "
Ответ 8
Вы можете использовать Email regexp, также убедившись, что проверка не завершится неудачно, если электронная почта пуста.
@Email(regexp = "[email protected]+\\..+|")
@Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@Documented
public @interface ExtendedEmail {
@OverridesAttribute(constraint = Email.class, name = "message")
String message() default "{javax.validation.constraints.Email.message}";
@OverridesAttribute(constraint = Email.class, name = "groups")
Class<?>[] groups() default {};
@OverridesAttribute(constraint = Email.class, name = "payload")
Class<? extends Payload>[] payload() default {};
}