Question

J'utilise l'annotation @Email pour valider une adresse e-mail. La question que je vais avoir est qu'il est d'accepter des choses comme ask@stackoverflow comme une adresse e-mail valide. Je suppose que cela est parce qu'ils veulent soutenir les adresses intranet, mais je ne peux pas sembler trouver un drapeau il ne vérifie une extension.

Ai-je vraiment besoin de passer à @Pattern (et des recommandations pour un modèle e-mail qui est flexible) ou suis-je manque quelque chose?

Était-ce utile?

La solution

En fait, @Email de Hibernate Validator uses regExp interne . Vous pouvez facilement définir votre propre contrainte en fonction de cette expression rationnelle, modifiée que vous avez besoin (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
                    + ")$";
}

Autres conseils

Vous pouvez également utiliser contrainte composition comme un travail autour. Dans l'exemple ci-dessous, je compte sur le validateur @Email faire la validation principale, et ajouter un validateur @Pattern pour vous assurer que l'adresse est sous forme de x@y.z (je ne recommande pas d'utiliser seulement le @Pattern ci-dessous pour la validation régulière Email)

@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 {};
}

En fait valider les adresses e-mail est vraiment complexe. Il est impossible de valider une adresse e-mail est à la fois syntaxiquement correcte et adresse du destinataire dans une annotation. L'annotation @Email est un contrôle minimal utile qui ne souffre pas du problème des faux négatifs.

L'étape suivante dans la validation devrait envoyer un e-mail à un défi que l'utilisateur doit remplir pour établir que l'utilisateur a accès à l'adresse e-mail.

Il est préférable d'être accepter quelques faux positifs à l'étape 1 et permettre à des adresses e-mail non valides de passer à travers que de rejeter les utilisateurs valides. Si vous voulez appliquer des règles supplémentaires que vous pouvez ajouter d'autres contrôles, mais faire très attention à ce que vous assumez une exigence d'une adresse e-mail valide. Par exemple, il n'y a rien dans les RFCs qui dicte que i@nl seraient invalides, parce que nl est un domaine de premier niveau national enregistré.

Voici un validateur email javax.validation utilisant 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();
    }
}

Il est évident que je suis en retard au Parti, encore je réponds à cette question,

Pourquoi ne puis nous utilisons l'annotation @Pattern avec des expressions régulières dans notre classe de validation comme celui-ci

public Class Sigunup {

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

}

Il est plus facile.

La solution de composition de contrainte ne fonctionne pas. Lorsque Email est utilisé en conjonction avec le modèle, l'e-mail regex est maintenu en priorité plus élevée. Je crois que c'est parce que l'annotation Email remplace quelques attributs de modèle, à savoir des drapeaux et des expressions rationnelles (celle clé ici) Si je supprime @Email, alors seulement l'expression régulière de @Pattern appliquer les 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 { };

Vous pouvez utiliser le courrier électronique regexp, ce qui assure également que la validation ne manque pas quand l'e-mail est vide.

@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 {};
}

Si vous allez essayer la solution ci-dessus https://stackoverflow.com/a/12515543/258544 add le @ReportAsSingleViolation dans le defination d'annotation, de cette façon, vous éviterez à la fois un message de validation (un de @Email et un de @Pattern) car il 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

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top