我正在使用 @Email 注释以验证电子邮件地址。我遇到的问题是它正在接受类似的东西 ask@stackoverflow 作为有效的电子邮件地址。我想这是因为他们想支持Intranet地址,但是我似乎找不到标志,因此它确实检查了扩展名。

我真的需要切换 @Pattern (以及关于灵活的电子邮件模式的任何建议)还是我错过了什么?

有帮助吗?

解决方案

实际上, @Email 来自Hibernate验证器 内部使用REGEXP. 。您可以根据需要修改的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
                    + ")$";
}

其他提示

您也可以使用 约束组成 作为一个工作。在下面的示例中,我依靠 @Email 验证器进行主要验证,并添加一个 @Pattern 验证器以确保地址为 x@y.z (我不建议仅使用 @Pattern 以下定期电子邮件验证)

@Email(message="Please provide a valid email address")
@Pattern(regexp=".+@.+\\..+", message="Please provide a valid email address")
@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@Documented
public @interface ExtendedEmailValidator {
    String message() default "Please provide a valid email address";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

实际验证电子邮件地址确实很复杂。不可能验证电子邮件地址在句法上是正确的,并且在注释中解决了预期的接收者。这 @Email 注释是一种有用的最小检查,不会遇到虚假负面问题。

验证的下一步应该是发送一封电子邮件,该电子邮件具有用户必须完成的挑战,以确定用户可以访问电子邮件地址。

最好在步骤1中接受一些误报,并允许一些无效的电子邮件地址通过,而不是拒绝有效的用户。如果要应用其他规则,则可以添加更多支票,但要谨慎地谨慎地认为您是有效电子邮件地址的要求。例如,RFC中没有任何决定 i@nl 将是无效的,因为 nl 是注册国家的顶级领域。

这是使用Apache Commons验证器的Javax.Validation电子邮件验证器

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();
    }
}

显然我迟到了聚会,但我仍然在回答这个问题,

为什么我们不能在这样的验证类中使用@pattern注释与正则表达式

public Class Sigunup {

    @NotNull
    @NotEmpty
    @Pattern((regexp="[A-Za-z0-9._%-+]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}")
    private String email;

}

它更容易。

约束组成解决方案不起作用。当电子邮件与模式结合使用时,电子邮件正则以更高的优先级保存。我相信这是因为电子邮件注释覆盖了一些模式属性,即标记和regexp(在此处键)(关键的话)(如果我删除) @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 { };

您可以使用电子邮件Regexp,还可以确保当电子邮件为空时验证不会失败。

@Email(regexp = ".+@.+\\..+|")
@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 {};
}

如果您要尝试上述解决方案 https://stackoverflow.com/a/12515543/258544 添加 @ReportAsSingleViolation 在注释定义中,这样您将避免两者既避免验证消息(一个来自 @Email 一个来自 @Pattern),因为它是一个构成的注释:

    @Email(message="Please provide a valid email address")
    @Pattern(regexp=".+@.+\\..+", message="Please provide a valid email address")
    @Target( { METHOD, FIELD, ANNOTATION_TYPE })
    @Retention(RUNTIME)
    @Constraint(validatedBy = {})
    @Documented
    @ReportAsSingleViolation

@interface ReportAsSingleViolation javax.validation:验证-API:1.1.0.-final)注释定义:“ ...对组成约束的评估在第一个验证错误上停止,以防构成约束用reportassingleviolation注释“

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top