Hibernate バリデータ:@Email は ask@stackoverflow を有効なものとして受け入れますか?
-
10-10-2019 - |
質問
私が使っているのは、 @Email
電子メール アドレスを検証するための注釈。私が抱えている問題は、次のようなものを受け入れていることです ask@stackoverflow
有効な電子メールアドレスとして。これはイントラネット アドレスをサポートしたいためだと思いますが、フラグが見つからないようなので、拡張子をチェックします。
本当に切り替える必要がありますか? @Pattern
(および柔軟な電子メール パターンに関する推奨事項) それとも何かが足りないのでしょうか?
解決
実際、 @Email
Hibernate Validatorから 内部で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でいくつかの誤検知を受け入れ、有効なユーザーを拒否するよりも、いくつかの無効な電子メールアドレスが通過できるようにすることをお勧めします。追加のルールを適用したい場合は、さらにチェックを追加できますが、有効な電子メールアドレスの要件であると仮定しているものに本当に注意してください。たとえば、RFCSにはそれを指示するものは何もありません i@nl
なぜなら、無効になるからです nl
登録国のトップレベルドメインです。
これがjavax.validationメールバリデーターを使用してApache Commons Valibatorを使用しています
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;
}
それは簡単です。
制約合成ソリューションは機能しません。電子メールをパターンと組み合わせて使用する場合、電子メール正規表現の方が優先されます。これは、電子メールのアノテーションがいくつかのパターン属性、つまりフラグと正規表現(ここで重要なもの)をオーバーライドするためだと思います。 @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
アノテーションの定義では、この方法で両方の検証メッセージを回避します(1つから @Email
と1つ @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。ファイナル)注釈の定義:「...構成制約の評価制約の評価制約がレポートレビオ化と注釈が付けられている場合の最初の検証エラーの停止」