Validateur d'hibernation: @Email accepte ask@stackoverflow comme valide?

j'utilise le @Email annotation pour valider une adresse e-mail. Le problème que j'ai est qu'il accepte des choses comme ask@stackoverflow comme une adresse e-mail valide. Je suppose que c'est parce qu'ils veulent prendre en charge les adresses intranet, mais je ne semble pas trouver un drapeau, donc il vérifie une extension.

ai-je vraiment besoin de passer à la <!-(Et toute recommandation pour un modèle d'e-mail qui est flexible) ou est-ce que je manque quelque chose?

44
demandé sur Andrii Abramov 2010-12-16 13:01:15

7 réponses

en Fait, @Email à partir de Hibernate Validator utilise regexp en interne. Vous pouvez facilement définir votre propre contrainte basée sur ce regexp, modifié comme vous le souhaitez (notez le + à la fin de 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
                    + ")$";
}
31
répondu axtavt 2013-10-01 09:58:31

vous pouvez aussi utiliser composition des contraintes comme solution de rechange. Dans l'exemple ci-dessous, je m'appuie sur l' @Email validateur pour faire le principal de validation, et d'ajouter un @Pattern validateur pour s'assurer que l'adresse est de la forme x@y.z (je ne recommande pas d'utiliser simplement les @Pattern ci-dessous pour la validation régulière du courriel)

@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 {};
}
42
répondu Matt 2017-06-13 07:08:27

la validation des adresses e-mail est très complexe. Il n'est pas possible de valider qu'une adresse e-mail est correcte sur le plan syntaxique et qu'elle s'adresse au destinataire dans une annotation. @Email l'annotation est une vérification minimale utile qui ne souffre pas du problème des faux négatifs.

La prochaine étape dans la validation devrait être l'envoi d'un e-mail avec un défi que l'utilisateur doit accomplir pour établir que l'utilisateur a accès à l'adresse e-mail adresse.

il est préférable d'accepter quelques faux positifs à l'étape 1 et de laisser passer des adresses e-mail invalides plutôt que de rejeter des utilisateurs valides. Si vous voulez appliquer des règles supplémentaires, vous pouvez ajouter plus de vérifications, mais faites très attention à ce que vous supposez être une exigence d'une adresse e-mail valide. Par exemple, il n'y a rien dans les RFC qui dicte que i@nl serait invalide, parce que nl est un domaine national enregistré de premier niveau.

13
répondu David 2017-06-13 07:08:46

Voici un javax.mail de validation du programme de validation à l'aide d'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);
    }
}

Et l'annotation:

@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();
    }
}
3
répondu Neil McGuigan 2015-09-04 21:55:26

LA solution de composition des contraintes ne fonctionne pas. Lorsque le courriel est utilisé en conjonction avec le motif, le regex de courriel est tenu dans la priorité supérieure. Je crois que c'est parce que l'annotation D'Email l'emporte sur quelques attributs de modèle, à savoir flags et regexp (la clé ici) si je supprime @Email, alors @Pattern l'expression régulière s'applique aux validations.

/**
 * @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 { };
0
répondu user1048931 2017-06-13 07:09:04

évidemment je suis en retard à la fête, pourtant je réponds à cette question,

pourquoi ne pouvons-nous pas utiliser @Pattern annotation avec des expressions régulières dans notre classe de Validation comme ceci

public Class Sigunup {

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

}

C'est plus facile.

0
répondu user2245151 2017-07-03 10:28:44

If you are going to try the above solution https://stackoverflow.com/a/12515543/258544 ajouter le @ReportAsSingleViolation dans l'annotation defination, de cette façon vous éviterez à la fois le message de validation (un de @Email et un de @Pattern) car c'est une annotation composée:

@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

From @interface ReportAsSingleViolation javax.validation:la validation de l'api:1.1.0.Final) annotation définition : "... L'évaluation des contraintes composées s'arrête sur la première validation erreur dans le cas où la contrainte de composition est annotée avec ReportAsSingleViolation"

0
répondu Francisco Quiñones 2018-07-18 03:43:08