Quelle est la meilleure méthode de validation D'adresse de courriel Java? [fermé]

quelles sont les bonnes bibliothèques de validation des adresses e-mail pour Java? Y a-t-il des alternatives au validateur commun ?

248
demandé sur Mark Rotteveel 2009-03-09 02:51:47

19 réponses

Apache Commons est généralement connu comme un projet solide. Gardez à l'esprit, cependant, vous aurez toujours à envoyer un email de vérification à l'adresse si vous voulez vous assurer qu'il est un vrai e-mail, et que le propriétaire veut qu'il soit utilisé sur votre site.

EDIT : il y avait un bug où il était trop restrictif sur le domaine, ce qui fait qu'il n'accepte pas les e-mails valides des nouveaux TLD.

ce bug était résolu 03/Jan/15 02:48 commons validator version 1.4.1

134
répondu Matthew Flaschen 2016-08-01 10:10:57

en utilisant le paquet de courrier électronique officiel de java est le plus facile:

public static boolean isValidEmailAddress(String email) {
   boolean result = true;
   try {
      InternetAddress emailAddr = new InternetAddress(email);
      emailAddr.validate();
   } catch (AddressException ex) {
      result = false;
   }
   return result;
}
261
répondu Aaron Davidson 2016-05-04 16:29:29

le validateur Apache Commons peut être utilisé comme indiqué dans les autres réponses.

pom.xml:

<dependency>
    <groupId>commons-validator</groupId>
    <artifactId>commons-validator</artifactId>
    <version>1.4.1</version>
</dependency>
"151950920 de construire".gradle:

compile 'commons-validator:commons-validator:1.4.1'

L'importation:

import org.apache.commons.validator.routines.EmailValidator;

le code:

String email = "myName@example.com";
boolean valid = EmailValidator.getInstance().isValid(email);

et pour permettre les adresses locales

boolean allowLocal = true;
boolean valid = EmailValidator.getInstance(allowLocal).isValid(email);
91
répondu Aksel Willgert 2015-12-12 10:37:41

réponse tardive, mais je pense qu'il est simple et digne:

    public boolean isValidEmailAddress(String email) {
           String ePattern = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$";
           java.util.regex.Pattern p = java.util.regex.Pattern.compile(ePattern);
           java.util.regex.Matcher m = p.matcher(email);
           return m.matches();
    }

Cas D'Essai :

enter image description here

aux fins de production, les validations de noms de domaine doivent être effectuées au niveau du réseau.

71
répondu Pujan Srivastava 2014-09-10 15:12:30

si vous essayez de faire une validation de formulaire reçue du client, ou juste une validation de fève - gardez le simple. Il est préférable de faire une validation de courrier électronique lâche plutôt que d'en faire une stricte et de rejeter certaines personnes, (par exemple quand ils essaient de s'inscrire à votre service web). Avec presque tout ce qui est autorisé dans la partie nom d'utilisateur de l'email et tant de nouveaux domaines sont ajoutés littéralement chaque mois (par exemple .entreprise. ,entreprise,.estate), il est plus sûr de ne pas être restrictif:

Pattern pattern = Pattern.compile("^.+@.+\..+$");
Matcher matcher = pattern.matcher(email);
21
répondu Alexander Burakevych 2014-06-20 06:08:20

en retard à la question, ici, mais: je maintiens une classe à cette adresse: http://lacinato.com/cm/software/emailrelated/emailaddress

il est basé sur la classe des Hazlewood, mais a de nombreuses améliorations et corrige quelques bugs. Licence Apache.

je crois que C'est L'analyseur de courrier électronique le plus capable en Java, et je dois encore voir un capable de plus dans n'importe quelle langue, bien qu'il puisse y avoir un là-bas. Ce n'est pas un lexer-style parser, mais utilise un certain complexe Java regex, et n'est donc pas aussi efficace qu'il pourrait l'être, mais mon entreprise a analysé bien plus de 10 milliards d'adresses dans le monde réel avec elle: il est certainement utilisable dans une situation de haute performance. Peut-être qu'une fois par an il va frapper une adresse qui provoque un débordement de la pile regex (de manière appropriée), mais ce sont des adresses spam qui sont des centaines ou des milliers de caractères de long avec beaucoup de nombreuses citations et les parenthèses et autres.

RFC 2822 et les spécifications sont vraiment assez permissif en termes d'adresses e-mail, donc une classe comme cela est trop pour la plupart des utilisations. Par exemple, ce qui suit est une adresse légitime, selon spec, espaces et tout:

"<bob \" (here) " < (hi there) "bob(the man)smith" (hi) @ (there) example.com (hello) > (again)

aucun serveur de messagerie ne permettrait cela, mais cette classe peut le parser (et le réécrire sous une forme utilisable).

nous avons constaté que les options Java email parser existantes ne sont pas suffisamment durables (ce qui signifie que toutes les options ne pas analyser quelques adresses valides), donc nous avons créé cette classe.

le code est bien documenté et offre de nombreuses options faciles à modifier pour autoriser ou refuser certains formulaires de courriel. Il fournit également un grand nombre de méthodes pour accéder à certaines parties de l'ADRESSE (côté gauche, côté droit, noms de personnes, commentaires, etc), pour analyser/valider les en-têtes mailbox-list, pour analyser/valider le chemin de retour (qui est unique parmi les en-têtes), et ainsi de suite.

le code comme written a une dépendance javamail, mais il est facile de l'enlever si vous ne voulez pas la fonctionnalité mineure qu'il fournit.

7
répondu lacinato 2012-10-30 06:36:22

je me demande juste pourquoi personne n'est venu avec @Email des contraintes supplémentaires de validateur Hibernate. Le validateur lui-même est EmailValidator .

7
répondu Markus Malkusch 2014-04-01 02:56:39

les Hazlewood a écrit une classe de validation de courrier électronique conforme RFC 2822 en utilisant des expressions régulières Java. Vous pouvez le trouver à http://www.leshazlewood.com/?p=23 . Cependant, sa minutie (ou la ré-implémentation Java) conduit à l'inefficacité - lire les commentaires sur les temps d'analyse pour les longues adresses.

5
répondu Philip 2009-08-24 10:49:27

j'ai porté une partie du code dans Zend_Validator_Email:

@FacesValidator("emailValidator")
public class EmailAddressValidator implements Validator {

    private String localPart;
    private String hostName;
    private boolean domain = true;

    Locale locale;
    ResourceBundle bundle;

    private List<FacesMessage> messages = new ArrayList<FacesMessage>();

    private HostnameValidator hostnameValidator;

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        setOptions(component);
        String email    = (String) value;
        boolean result  = true;
        Pattern pattern = Pattern.compile("^(.+)@([^@]+[^.])$");
        Matcher matcher = pattern.matcher(email);

        locale = context.getViewRoot().getLocale();
        bundle = ResourceBundle.getBundle("com.myapp.resources.validationMessages", locale);

        boolean length = true;
        boolean local  = true;

        if (matcher.find()) {
            localPart   = matcher.group(1);
            hostName    = matcher.group(2);

            if (localPart.length() > 64 || hostName.length() > 255) {
                length          = false;
                addMessage("enterValidEmail", "email.AddressLengthExceeded");
            } 

            if (domain == true) {
                hostnameValidator = new HostnameValidator();
                hostnameValidator.validate(context, component, hostName);
            }

            local = validateLocalPart();

            if (local && length) {
                result = true;
            } else {
                result = false;
            }

        } else {
            result          = false;
            addMessage("enterValidEmail", "invalidEmailAddress");
        }

        if (result == false) {
            throw new ValidatorException(messages);
        }

    }

    private boolean validateLocalPart() {
        // First try to match the local part on the common dot-atom format
        boolean result = false;

        // Dot-atom characters are: 1*atext *("." 1*atext)
        // atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*",
        //        "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~"
        String atext = "a-zA-Z0-9\u0021\u0023\u0024\u0025\u0026\u0027\u002a"
                + "\u002b\u002d\u002f\u003d\u003f\u005e\u005f\u0060\u007b"
                + "\u007c\u007d\u007e";
        Pattern regex = Pattern.compile("^["+atext+"]+(\u002e+["+atext+"]+)*$");
        Matcher matcher = regex.matcher(localPart);
        if (matcher.find()) {
            result = true;
        } else {
            // Try quoted string format

            // Quoted-string characters are: DQUOTE *([FWS] qtext/quoted-pair) [FWS] DQUOTE
            // qtext: Non white space controls, and the rest of the US-ASCII characters not
            //   including "\" or the quote character
            String noWsCtl = "\u0001-\u0008\u000b\u000c\u000e-\u001f\u007f";
            String qText = noWsCtl + "\u0021\u0023-\u005b\u005d-\u007e";
            String ws = "\u0020\u0009";

            regex = Pattern.compile("^\u0022(["+ws+qText+"])*["+ws+"]?\u0022$");
            matcher = regex.matcher(localPart);
            if (matcher.find()) {
                result = true;
            } else {
                addMessage("enterValidEmail", "email.AddressDotAtom");
                addMessage("enterValidEmail", "email.AddressQuotedString");
                addMessage("enterValidEmail", "email.AddressInvalidLocalPart");
            }
        }

        return result;
    }

    private void addMessage(String detail, String summary) {
        String detailMsg = bundle.getString(detail);
        String summaryMsg = bundle.getString(summary);
        messages.add(new FacesMessage(FacesMessage.SEVERITY_ERROR, summaryMsg, detailMsg));
    }

    private void setOptions(UIComponent component) {
        Boolean domainOption = Boolean.valueOf((String) component.getAttributes().get("domain"));
        //domain = (domainOption == null) ? true : domainOption.booleanValue();
    }
}

avec un validateur de nom d'hôte comme suit:

@FacesValidator("hostNameValidator")
public class HostnameValidator implements Validator {

    private Locale locale;
    private ResourceBundle bundle;
    private List<FacesMessage> messages;
    private boolean checkTld = true;
    private boolean allowLocal = false;
    private boolean allowDNS = true;
    private String tld;
    private String[] validTlds = {"ac", "ad", "ae", "aero", "af", "ag", "ai",
        "al", "am", "an", "ao", "aq", "ar", "arpa", "as", "asia", "at", "au",
        "aw", "ax", "az", "ba", "bb", "bd", "be", "bf", "bg", "bh", "bi", "biz",
        "bj", "bm", "bn", "bo", "br", "bs", "bt", "bv", "bw", "by", "bz", "ca",
        "cat", "cc", "cd", "cf", "cg", "ch", "ci", "ck", "cl", "cm", "cn", "co",
        "com", "coop", "cr", "cu", "cv", "cx", "cy", "cz", "de", "dj", "dk",
        "dm", "do", "dz", "ec", "edu", "ee", "eg", "er", "es", "et", "eu", "fi",
        "fj", "fk", "fm", "fo", "fr", "ga", "gb", "gd", "ge", "gf", "gg", "gh",
        "gi", "gl", "gm", "gn", "gov", "gp", "gq", "gr", "gs", "gt", "gu", "gw",
        "gy", "hk", "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "im", "in",
        "info", "int", "io", "iq", "ir", "is", "it", "je", "jm", "jo", "jobs",
        "jp", "ke", "kg", "kh", "ki", "km", "kn", "kp", "kr", "kw", "ky", "kz",
        "la", "lb", "lc", "li", "lk", "lr", "ls", "lt", "lu", "lv", "ly", "ma",
        "mc", "md", "me", "mg", "mh", "mil", "mk", "ml", "mm", "mn", "mo",
        "mobi", "mp", "mq", "mr", "ms", "mt", "mu", "museum", "mv", "mw", "mx",
        "my", "mz", "na", "name", "nc", "ne", "net", "nf", "ng", "ni", "nl",
        "no", "np", "nr", "nu", "nz", "om", "org", "pa", "pe", "pf", "pg", "ph",
        "pk", "pl", "pm", "pn", "pr", "pro", "ps", "pt", "pw", "py", "qa", "re",
        "ro", "rs", "ru", "rw", "sa", "sb", "sc", "sd", "se", "sg", "sh", "si",
        "sj", "sk", "sl", "sm", "sn", "so", "sr", "st", "su", "sv", "sy", "sz",
        "tc", "td", "tel", "tf", "tg", "th", "tj", "tk", "tl", "tm", "tn", "to",
        "tp", "tr", "travel", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "um",
        "us", "uy", "uz", "va", "vc", "ve", "vg", "vi", "vn", "vu", "wf", "ws",
        "ye", "yt", "yu", "za", "zm", "zw"};
    private Map<String, Map<Integer, Integer>> idnLength;

    private void init() {
        Map<Integer, Integer> biz = new HashMap<Integer, Integer>();
        biz.put(5, 17);
        biz.put(11, 15);
        biz.put(12, 20);

        Map<Integer, Integer> cn = new HashMap<Integer, Integer>();
        cn.put(1, 20);

        Map<Integer, Integer> com = new HashMap<Integer, Integer>();
        com.put(3, 17);
        com.put(5, 20);

        Map<Integer, Integer> hk = new HashMap<Integer, Integer>();
        hk.put(1, 15);

        Map<Integer, Integer> info = new HashMap<Integer, Integer>();
        info.put(4, 17);

        Map<Integer, Integer> kr = new HashMap<Integer, Integer>();
        kr.put(1, 17);

        Map<Integer, Integer> net = new HashMap<Integer, Integer>();
        net.put(3, 17);
        net.put(5, 20);

        Map<Integer, Integer> org = new HashMap<Integer, Integer>();
        org.put(6, 17);

        Map<Integer, Integer> tw = new HashMap<Integer, Integer>();
        tw.put(1, 20);

        Map<Integer, Integer> idn1 = new HashMap<Integer, Integer>();
        idn1.put(1, 20);

        Map<Integer, Integer> idn2 = new HashMap<Integer, Integer>();
        idn2.put(1, 20);

        Map<Integer, Integer> idn3 = new HashMap<Integer, Integer>();
        idn3.put(1, 20);

        Map<Integer, Integer> idn4 = new HashMap<Integer, Integer>();
        idn4.put(1, 20);

        idnLength = new HashMap<String, Map<Integer, Integer>>();

        idnLength.put("BIZ", biz);
        idnLength.put("CN", cn);
        idnLength.put("COM", com);
        idnLength.put("HK", hk);
        idnLength.put("INFO", info);
        idnLength.put("KR", kr);
        idnLength.put("NET", net);
        idnLength.put("ORG", org);
        idnLength.put("TW", tw);
        idnLength.put("ایران", idn1);
        idnLength.put("中国", idn2);
        idnLength.put("公司", idn3);
        idnLength.put("网络", idn4);

        messages = new ArrayList<FacesMessage>();
    }

    public HostnameValidator() {
        init();
    }

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        String hostName = (String) value;

        locale = context.getViewRoot().getLocale();
        bundle = ResourceBundle.getBundle("com.myapp.resources.validationMessages", locale);

        Pattern ipPattern = Pattern.compile("^[0-9a-f:\.]*$", Pattern.CASE_INSENSITIVE);
        Matcher ipMatcher = ipPattern.matcher(hostName);
        if (ipMatcher.find()) {
            addMessage("hostname.IpAddressNotAllowed");
            throw new ValidatorException(messages);
        }

        boolean result = false;

        // removes last dot (.) from hostname 
        hostName = hostName.replaceAll("(\.)+$", "");
        String[] domainParts = hostName.split("\.");

        boolean status = false;

        // Check input against DNS hostname schema
        if ((domainParts.length > 1) && (hostName.length() > 4) && (hostName.length() < 255)) {
            status = false;

            dowhile:
            do {
                // First check TLD
                int lastIndex = domainParts.length - 1;
                String domainEnding = domainParts[lastIndex];
                Pattern tldRegex = Pattern.compile("([^.]{2,10})", Pattern.CASE_INSENSITIVE);
                Matcher tldMatcher = tldRegex.matcher(domainEnding);
                if (tldMatcher.find() || domainEnding.equals("ایران")
                        || domainEnding.equals("中国")
                        || domainEnding.equals("公司")
                        || domainEnding.equals("网络")) {



                    // Hostname characters are: *(label dot)(label dot label); max 254 chars
                    // label: id-prefix [*ldh{61} id-prefix]; max 63 chars
                    // id-prefix: alpha / digit
                    // ldh: alpha / digit / dash

                    // Match TLD against known list
                    tld = (String) tldMatcher.group(1).toLowerCase().trim();
                    if (checkTld == true) {
                        boolean foundTld = false;
                        for (int i = 0; i < validTlds.length; i++) {
                            if (tld.equals(validTlds[i])) {
                                foundTld = true;
                            }
                        }

                        if (foundTld == false) {
                            status = false;
                            addMessage("hostname.UnknownTld");
                            break dowhile;
                        }
                    }

                    /**
                     * Match against IDN hostnames
                     * Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames
                     */
                    List<String> regexChars = getIdnRegexChars();

                    // Check each hostname part
                    int check = 0;
                    for (String domainPart : domainParts) {
                        // Decode Punycode domainnames to IDN
                        if (domainPart.indexOf("xn--") == 0) {
                            domainPart = decodePunycode(domainPart.substring(4));
                        }

                        // Check dash (-) does not start, end or appear in 3rd and 4th positions
                        if (domainPart.indexOf("-") == 0
                                || (domainPart.length() > 2 && domainPart.indexOf("-", 2) == 2 && domainPart.indexOf("-", 3) == 3)
                                || (domainPart.indexOf("-") == (domainPart.length() - 1))) {
                            status = false;
                            addMessage("hostname.DashCharacter");
                            break dowhile;
                        }

                        // Check each domain part
                        boolean checked = false;

                        for (int key = 0; key < regexChars.size(); key++) {
                            String regexChar = regexChars.get(key);
                            Pattern regex = Pattern.compile(regexChar);
                            Matcher regexMatcher = regex.matcher(domainPart);
                            status = regexMatcher.find();
                            if (status) {
                                int length = 63;

                                if (idnLength.containsKey(tld.toUpperCase())
                                        && idnLength.get(tld.toUpperCase()).containsKey(key)) {
                                    length = idnLength.get(tld.toUpperCase()).get(key);
                                }

                                int utf8Length;
                                try {
                                    utf8Length = domainPart.getBytes("UTF8").length;
                                    if (utf8Length > length) {
                                        addMessage("hostname.InvalidHostname");
                                    } else {
                                        checked = true;
                                        break;
                                    }
                                } catch (UnsupportedEncodingException ex) {
                                    Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
                                }


                            }
                        }


                        if (checked) {
                            ++check;
                        }
                    }

                    // If one of the labels doesn't match, the hostname is invalid
                    if (check != domainParts.length) {
                        status = false;
                        addMessage("hostname.InvalidHostnameSchema");

                    }
                } else {
                    // Hostname not long enough
                    status = false;
                    addMessage("hostname.UndecipherableTld");
                }

            } while (false);

            if (status == true && allowDNS) {
                result = true;
            }

        } else if (allowDNS == true) {
            addMessage("hostname.InvalidHostname");
            throw new ValidatorException(messages);
        }

        // Check input against local network name schema;
        Pattern regexLocal = Pattern.compile("^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}){1,254}$", Pattern.CASE_INSENSITIVE);
        boolean checkLocal = regexLocal.matcher(hostName).find();
        if (allowLocal && !status) {
            if (checkLocal) {
                result = true;
            } else {
                // If the input does not pass as a local network name, add a message
                result = false;
                addMessage("hostname.InvalidLocalName");
            }
        }


        // If local network names are not allowed, add a message
        if (checkLocal && !allowLocal && !status) {
            result = false;
            addMessage("hostname.LocalNameNotAllowed");
        }

        if (result == false) {
            throw new ValidatorException(messages);
        }

    }

    private void addMessage(String msg) {
        String bundlMsg = bundle.getString(msg);
        messages.add(new FacesMessage(FacesMessage.SEVERITY_ERROR, bundlMsg, bundlMsg));
    }

    /**
     * Returns a list of regex patterns for the matched TLD
     * @param tld
     * @return 
     */
    private List<String> getIdnRegexChars() {
        List<String> regexChars = new ArrayList<String>();
        regexChars.add("^[a-z0-9\x2d]{1,63}$");
        Document doc = null;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);

        try {
            InputStream validIdns = getClass().getClassLoader().getResourceAsStream("com/myapp/resources/validIDNs_1.xml");
            DocumentBuilder builder = factory.newDocumentBuilder();
            doc = builder.parse(validIdns);
            doc.getDocumentElement().normalize();
        } catch (SAXException ex) {
            Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
        }

        // prepare XPath
        XPath xpath = XPathFactory.newInstance().newXPath();

        NodeList nodes = null;
        String xpathRoute = "//idn[tld=\'" + tld.toUpperCase() + "\']/pattern/text()";

        try {
            XPathExpression expr;
            expr = xpath.compile(xpathRoute);
            Object res = expr.evaluate(doc, XPathConstants.NODESET);
            nodes = (NodeList) res;
        } catch (XPathExpressionException ex) {
            Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
        }


        for (int i = 0; i < nodes.getLength(); i++) {
            regexChars.add(nodes.item(i).getNodeValue());
        }

        return regexChars;
    }

    /**
     * Decode Punycode string
     * @param encoded
     * @return 
         */
    private String decodePunycode(String encoded) {
        Pattern regex = Pattern.compile("([^a-z0-9\x2d]{1,10})", Pattern.CASE_INSENSITIVE);
        Matcher matcher = regex.matcher(encoded);
        boolean found = matcher.find();

        if (encoded.isEmpty() || found) {
            // no punycode encoded string, return as is
            addMessage("hostname.CannotDecodePunycode");
            throw new ValidatorException(messages);
        }

        int separator = encoded.lastIndexOf("-");
            List<Integer> decoded = new ArrayList<Integer>();
        if (separator > 0) {
            for (int x = 0; x < separator; ++x) {
                decoded.add((int) encoded.charAt(x));
            }
        } else {
            addMessage("hostname.CannotDecodePunycode");
            throw new ValidatorException(messages);
        }

        int lengthd = decoded.size();
        int lengthe = encoded.length();

        // decoding
        boolean init = true;
        int base = 72;
        int index = 0;
        int ch = 0x80;

        int indexeStart = (separator == 1) ? (separator + 1) : 0;
        for (int indexe = indexeStart; indexe < lengthe; ++lengthd) {
            int oldIndex = index;
            int pos = 1;
            for (int key = 36; true; key += 36) {
                int hex = (int) encoded.charAt(indexe++);
                int digit = (hex - 48 < 10) ? hex - 22
                        : ((hex - 65 < 26) ? hex - 65
                        : ((hex - 97 < 26) ? hex - 97
                        : 36));

                index += digit * pos;
                int tag = (key <= base) ? 1 : ((key >= base + 26) ? 26 : (key - base));
                if (digit < tag) {
                    break;
                }
                pos = (int) (pos * (36 - tag));
            }
            int delta = (int) (init ? ((index - oldIndex) / 700) : ((index - oldIndex) / 2));
            delta += (int) (delta / (lengthd + 1));
            int key;
            for (key = 0; delta > 910; key += 36) {
                delta = (int) (delta / 35);
            }
            base = (int) (key + 36 * delta / (delta + 38));
            init = false;
            ch += (int) (index / (lengthd + 1));
            index %= (lengthd + 1);
            if (lengthd > 0) {
                for (int i = lengthd; i > index; i--) {
                    decoded.set(i, decoded.get(i - 1));
                }
            }

            decoded.set(index++, ch);
        }

        // convert decoded ucs4 to utf8 string
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < decoded.size(); i++) {
            int value = decoded.get(i);
            if (value < 128) {
                sb.append((char) value);
            } else if (value < (1 << 11)) {
                sb.append((char) (192 + (value >> 6)));
                sb.append((char) (128 + (value & 63)));
            } else if (value < (1 << 16)) {
                sb.append((char) (224 + (value >> 12)));
                sb.append((char) (128 + ((value >> 6) & 63)));
                sb.append((char) (128 + (value & 63)));
            } else if (value < (1 << 21)) {
                sb.append((char) (240 + (value >> 18)));
                sb.append((char) (128 + ((value >> 12) & 63)));
                sb.append((char) (128 + ((value >> 6) & 63)));
                sb.append((char) (128 + (value & 63)));
            } else {
                addMessage("hostname.CannotDecodePunycode");
                throw new ValidatorException(messages);
            }
        }

        return sb.toString();

    }

    /**
     * Eliminates empty values from input array
     * @param data
     * @return 
     */
    private String[] verifyArray(String[] data) {
        List<String> result = new ArrayList<String>();
        for (String s : data) {
            if (!s.equals("")) {
                result.add(s);
            }
        }

        return result.toArray(new String[result.size()]);
    }
}

et un validIDNs.xml avec la regex pour les motifs des différents tld (trop grand pour comprendre:)

<idnlist>
    <idn>
        <tld>AC</tld>
        <pattern>^[\u002d0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>AR</tld>
        <pattern>^[\u002d0-9a-zà-ãç-êìíñ-õü]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>AS</tld>
        <pattern>/^[\u002d0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>AT</tld>
        <pattern>/^[\u002d0-9a-zà-öø-ÿœšž]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>BIZ</tld>
        <pattern>^[\u002d0-9a-zäåæéöøü]{1,63}$</pattern>
        <pattern>^[\u002d0-9a-záéíñóúü]{1,63}$</pattern>
        <pattern>^[\u002d0-9a-záéíóöúüőű]{1,63}$</pattern>
    </id>
</idlist>
3
répondu Erick Martinez 2011-07-12 23:57:00
public class Validations {

    private Pattern regexPattern;
    private Matcher regMatcher;

    public String validateEmailAddress(String emailAddress) {

        regexPattern = Pattern.compile("^[(a-zA-Z-0-9-\_\+\.)]+@[(a-z-A-z)]+\.[(a-zA-z)]{2,3}$");
        regMatcher   = regexPattern.matcher(emailAddress);
        if(regMatcher.matches()) {
            return "Valid Email Address";
        } else {
            return "Invalid Email Address";
        }
    }

    public String validateMobileNumber(String mobileNumber) {
        regexPattern = Pattern.compile("^\+[0-9]{2,3}+-[0-9]{10}$");
        regMatcher   = regexPattern.matcher(mobileNumber);
        if(regMatcher.matches()) {
            return "Valid Mobile Number";
        } else {
            return "Invalid Mobile Number";
        }
    }

    public static void main(String[] args) {

        String emailAddress = "suryaprakash.pisay@gmail.com";
        String mobileNumber = "+91-9986571622";
        Validations validations = new Validations();
        System.out.println(validations.validateEmailAddress(emailAddress));
        System.out.println(validations.validateMobileNumber(mobileNumber));
    }
}
3
répondu Suryaprakash Pisay 2017-06-15 10:24:11

si vous cherchez à vérifier si une adresse e-mail est valide, alors VRFY vous obtiendrez une partie du chemin. J'ai trouvé que c'est utile pour valider les adresses intranet (c'est-à-dire, les adresses e-mail pour les sites internes). Cependant, il est moins utile pour les serveurs de messagerie internet (voir les mises en garde en haut de cette page)

2
répondu Brian Agnew 2009-03-09 10:16:56

bien qu'il existe de nombreuses alternatives à Apache commons, leurs implémentations sont au mieux rudimentaires (comme Apache commons' implementation elle-même) et même totalement erronées dans d'autres cas.

Je m'éloignerais aussi de ce que l'on appelle le simple "non restrictif" regex; il n'y a pas une telle chose. Par exemple @ est autorisé plusieurs fois selon le contexte, comment savez-vous que celui requis est là? Simple regex ne veut pas le comprendre, même si l'e-mail doit être valide. Tout plus complexe devient sujet à erreur ou même contenir tueurs à performance cachés . Comment allez-vous maintenir quelque chose comme ce ?

le seul validateur basé sur regex conforme à la RFC que je connaisse est email-rfc2822-validator avec son regex "raffiné" correctement nommé Dragons.java . Il prend en charge seulement l'ancien RFC-2822 spécifications cependant, bien que suffisamment approprié pour les besoins modernes (RFC-5322 mises à jour it dans les zones déjà hors de portée pour les cas d'utilisation quotidienne).

mais vraiment ce que vous voulez est un lexer qui divise correctement une chaîne et la divise en la structure du composant selon la grammaire du RFC. EmailValidator4J semble prometteur à cet égard, mais il est encore jeune et limité.

une autre option que vous avez est d'utiliser un service Web comme validation webservice ou API Mailboxlayer (vient de prendre les premiers résultats Google). Il n'est pas strictement conforme à la RFC, mais fonctionne assez bien pour les besoins modernes.

2
répondu Benny Bottema 2018-01-03 05:42:58

que voulez-vous valider? L'adresse e-mail?

l'adresse e-mail ne peut être vérifiée que pour sa conformité au format. Voir la norme: RFC2822 . La meilleure façon de le faire est une expression régulière. Vous ne saurez jamais si existe vraiment sans envoyer un e-mail.

j'ai vérifié le validateur commun. Il contient un org.Apache.commun.validateurs.Classe EmailValidator. Semble être un bon point de départ.

1
répondu ReneS 2009-03-09 01:09:41

la version courante du validateur Apache Commons est 1.3.1 .

classe qui valide est org.Apache.commun.validateurs.EmailValidator. Il a une importation pour org.Apache.oro.texte.Perl.Perl5Util qui est d'un retraité Jakarta ORO project .

BTW, j'ai trouvé qu'il y a une version 1.4, voici les docs API . Sur le site " il dit: "Dernière Publication: 05 Mars 2008 | Version: 1.4-SNAPSHOT", mais ce n'est pas définitive. Seule façon de construire vous-même (mais il s'agit d'un instantané, pas de libération) et utiliser, ou télécharger à partir de ici . Cela signifie que la version 1.4 n'a pas été rendue définitive avant Trois ans (2008-2011). Ce n'est pas dans le style. Je cherche une meilleure option, mais je n'en ai pas trouvé une qui soit très adoptée. Je veux utiliser quelque chose qui est bien testé, Je ne veux pas de bugs.

1
répondu mist 2011-04-03 18:03:53

Vous pouvez également vérifier la longueur de courriels à un maximum de 254 caractères. J'utilise le validateur Apache commons et il ne vérifie pas cela.

0
répondu minglis 2010-11-09 15:39:54

il ne semble pas y avoir de bibliothèques parfaites ou de moyens pour le faire vous-même, à moins que vous ayez à envoyer un e-mail à l'adresse e-mail et d'attendre une réponse (cela pourrait ne pas être une option cependant). J'ai fini par utiliser une suggestion d'ici http://blog.logichigh.com/2010/09/02/validating-an-e-mail-address / et en ajustant le code pour qu'il fonctionne en Java.

public static boolean isValidEmailAddress(String email) {
    boolean stricterFilter = true; 
    String stricterFilterString = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}";
    String laxString = ".+@.+\.[A-Za-z]{2}[A-Za-z]*";
    String emailRegex = stricterFilter ? stricterFilterString : laxString;
    java.util.regex.Pattern p = java.util.regex.Pattern.compile(emailRegex);
    java.util.regex.Matcher m = p.matcher(email);
    return m.matches();
}
-2
répondu matt.writes.code 2013-09-30 22:24:55

C'est la meilleure méthode:

public static boolean isValidEmail(String enteredEmail){
        String EMAIL_REGIX = "^[\\w!#$%&’*+/=?`{|}~^-]+(?:\\.[\\w!#$%&’*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$";
        Pattern pattern = Pattern.compile(EMAIL_REGIX);
        Matcher matcher = pattern.matcher(enteredEmail);
        return ((!enteredEmail.isEmpty()) && (enteredEmail!=null) && (matcher.matches()));
    }

Sources:- http://howtodoinjava.com/2014/11/11/java-regex-validate-email-address /

http://www.rfc-editor.org/rfc/rfc5322.txt

-2
répondu Pravinsingh Waghela 2015-10-15 13:08:05

une autre option est d'utiliser le Hibernate Email validator , en utilisant l'annotation @Email ou en utilisant la classe validator programmatically, comme:

import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator; 

class Validator {
    // code
    private boolean isValidEmail(String email) {
        EmailValidator emailValidator = new EmailValidator();
        return emailValidator.isValid(email, null);
    }

}
-2
répondu Dherik 2017-12-18 19:48:20

est mon approche pragmatique, où je veux juste des adresses blah@domain distinctes raisonnables en utilisant les caractères autorisés de la RFC. Les adresses doivent être converties en minuscules au préalable.

public class EmailAddressValidator {

    private static final String domainChars = "a-z0-9\-";
    private static final String atomChars = "a-z0-9\Q!#$%&'*+-/=?^_`{|}~\E";
    private static final String emailRegex = "^" + dot(atomChars) + "@" + dot(domainChars) + "$";
    private static final Pattern emailPattern = Pattern.compile(emailRegex);

    private static String dot(String chars) {
        return "[" + chars + "]+(?:\.[" + chars + "]+)*";
    }

    public static boolean isValidEmailAddress(String address) {
        return address != null && emailPattern.matcher(address).matches();
    }

}
-3
répondu Craig Day 2016-01-20 03:11:07