Подтвердить что ты не робот

Hibernate validator: @Email принимает запрос @stackoverflow как действительный?

Я использую аннотацию @Email для проверки адреса электронной почты. Проблема, с которой я сталкиваюсь, заключается в том, что он принимает такие вещи, как [email protected], как действительный адрес электронной почты. Я предполагаю, что это потому, что они хотят поддерживать адреса интрасети, но я не могу найти флаг, поэтому он проверяет расширение.

Мне действительно нужно переключиться на @Pattern (и любые рекомендации по шаблону электронной почты, который является гибким), или я что-то не хватает?

4b9b3361

Ответ 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 {};
}