我正在使用@Email
注释来验证电子邮件地址。
我遇到的问题是,它接受ask@stackoverflow
之类的内容作为有效的电子邮件地址。
我想这是因为他们想要支持内部网地址,但我似乎无法找到一个标志,因此它会检查扩展名。
我是否真的需要切换到@Pattern
(以及针对电子邮件模式的任何灵活建议)或者我是否遗漏了某些内容?
答案 0 :(得分:49)
您也可以使用constraint composition作为解决方法。在下面的示例中,我依靠@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 {};
}
答案 1 :(得分:33)
实际上,来自Hibernate Validator uses regexp internally的@Email
。您可以根据正则表达式轻松定义自己的约束,并根据需要进行修改(请注意+
末尾的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 :(得分:15)
实际验证电子邮件地址确实非常复杂。无法验证电子邮件地址在语法上是否正确并且在注释中寻址预期收件人。 @Email
注释是一个有用的最小检查,不会出现漏报问题。
验证的下一步应该是发送一封电子邮件,其中包含用户必须完成的质询,以确定用户是否可以访问该电子邮件地址。
最好在步骤1中接受一些误报并允许一些无效的电子邮件地址通过,而不是拒绝有效的用户。如果要应用其他规则,可以添加更多检查,但要非常小心您认为有效电子邮件地址的要求。例如,RFC中没有任何内容表明i@nl
无效,因为nl
是注册的国家/地区顶级域名。
答案 3 :(得分:3)
这是使用Apache Commons Validator的javax.validation电子邮件验证程序
SELECT area, max(age), min(age), avg(age)
FROM mydb
GROUP BY area
注释:
with open('<file>', 'r+') as f:
for line_no, line in enumerate(f):
if line_no == 5: # read 5 lines
f.seek(18, 1) # jump forward 18 characters
f.write("{: 8d}".format(s2)) # overwrite with padded s2 (int)
break
答案 4 :(得分:3)
尽管仍然可以实现自己的验证器或编写将@Email
和@Pattern
聚合在一起的自定义验证器,但您不必再这样做了!
在最近的发行版中(肯定存在于hibernate-validator 6.0.x中),@Email
获得了新的regexp
属性,即“带注释的元素必须匹配的附加正则表达式” 。换句话说,这是一种新方法:
@Email(regexp = ".+@.+\\..+")
private String email;
答案 5 :(得分:0)
约束组合解决方案不起作用。当电子邮件与Pattern一起使用时,电子邮件正则表达式保持更高的优先级。我相信这是因为Email注释会覆盖一些Pattern属性,即flags和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 { };
答案 6 :(得分:0)
显然我迟到了党,我仍在回答这个问题,
为什么我们不能在我们的验证类中使用带有正则表达式的@Pattern注释,如此
public Class Sigunup {
@NotNull
@NotEmpty
@Pattern((regexp="[A-Za-z0-9._%-+]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}")
private String email;
}
它更容易。
答案 7 :(得分:0)
如果您要尝试上述解决方案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:validation-api:1.1.0.Final)注释定义: “ ...对组合约束的评估在第一次验证时停止 如果使用ReportAsSingleViolation注释构成约束,则会出现错误”
答案 8 :(得分:0)
您可以使用电子邮件正则表达式,还可以确保电子邮件为空时验证不会失败。
@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 {};
}