@Email
電子メールアドレスを検証するために注釈を使用しています。私が抱えている問題はask@stackoverflow
、有効な電子メールアドレスなどを受け入れていることです。これは、イントラネットアドレスをサポートしたいためだと思いますが、フラグが見つからないため、拡張子をチェックします。
本当に切り替える必要があり@Pattern
ますか(そして柔軟な電子メールパターンの推奨事項)、それとも何かが足りませんか?
@Email
電子メールアドレスを検証するために注釈を使用しています。私が抱えている問題はask@stackoverflow
、有効な電子メールアドレスなどを受け入れていることです。これは、イントラネットアドレスをサポートしたいためだと思いますが、フラグが見つからないため、拡張子をチェックします。
本当に切り替える必要があり@Pattern
ますか(そして柔軟な電子メールパターンの推奨事項)、それとも何かが足りませんか?
回避策としてコンストレイン合成を使用することもできます。@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
HibernateValidatorからは内部で正規表現を使用しています。その正規表現に基づいて、必要に応じて変更された独自の制約を簡単に定義できます(+
の最後にあることに注意してください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
偽陰性の問題に悩まされない便利な最小限のチェックです。
検証の次のステップは、電子メール アドレスにアクセスできることを確認するために、ユーザーが完了しなければならないチャレンジを含む電子メールを送信することです。
有効なユーザーを拒否するよりも、手順 1 でいくつかの誤検出を受け入れ、無効な電子メール アドレスを通過させる方が適切です。追加のルールを適用したい場合は、さらにチェックを追加できますが、有効な電子メール アドレスの要件であると想定するものについては十分に注意してください。たとえば、RFC には、登録された国のトップレベル ドメインi@nl
であるため、それが無効であると指示するものは何もありません。nl
これは、Apache Commons Validator を使用した 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();
}
}
制約合成ソリューションは機能しません。Email を Pattern と組み合わせて使用すると、Email 正規表現が優先されます。これは、Email アノテーションがいくつかのパターン属性、つまり 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 { };