Java için iyi e-posta adresi doğrulama kitaplıkları nelerdir? Ortak doğrulayıcıya alternatif var mı?
Java için iyi e-posta adresi doğrulama kitaplıkları nelerdir? Ortak doğrulayıcıya alternatif var mı?
Yanıtlar:
Apache Commons genellikle sağlam bir proje olarak bilinir. Yine de, bunun gerçek bir e-posta olduğundan ve sahibinin sitenizde kullanılmasını istediğinden emin olmak istiyorsanız adrese bir doğrulama e-postası göndermeniz gerektiğini unutmayın.
EDIT : Alan adında çok kısıtlayıcı olduğu ve yeni TLD'lerden geçerli e-postaları kabul etmemesine neden olan bir hata oluştu.
Bu hata 03 / Oca / 15 02:48 tarihinde commons-validator 1.4.1 sürümünde giderilmiştir.
EmailValidator
sınıfı doğrulama için bir e-posta mesajı göndermez.
Kullanılması resmi java e-posta paketi en kolay:
public static boolean isValidEmailAddress(String email) {
boolean result = true;
try {
InternetAddress emailAddr = new InternetAddress(email);
emailAddr.validate();
} catch (AddressException ex) {
result = false;
}
return result;
}
.
, .com
, com.
, abc
ve 123
. Ayrıca, öndeki veya sondaki boşluk eklemek de dizeleri geçersiz kılmaz. Hakim siz olun!
Apache Commons validator diğer cevaplarda belirtildiği gibi kullanılabilir.
pom.xml:
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.4.1</version>
</dependency>
build.gradle:
compile 'commons-validator:commons-validator:1.4.1'
İçe aktarma:
import org.apache.commons.validator.routines.EmailValidator;
Kod:
String email = "myName@example.com";
boolean valid = EmailValidator.getInstance().isValid(email);
ve yerel adreslere izin vermek için
boolean allowLocal = true;
boolean valid = EmailValidator.getInstance(allowLocal).isValid(email);
Geç cevap, ama bence basit ve değerli:
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();
}
Test Durumları :
Üretim amacıyla Alan Adı doğrulamaları ağ üzerinden gerçekleştirilmelidir.
İstemciden alınan bir form doğrulaması veya sadece bir fasulye doğrulaması yapmaya çalışıyorsanız, bunu basit tutun. Sıkı bir e-posta doğrulaması yapmak ve bazı kişileri reddetmek yerine (örneğin, web hizmetinize kaydolmaya çalışırken) gevşek bir e-posta doğrulaması yapmak daha iyidir. E-postanın kullanıcı adı bölümünde neredeyse her şeye izin verilir ve her ay kelimenin tam anlamıyla çok sayıda yeni alan eklenir (ör. Şirket, .entreprise, .estate), kısıtlayıcı olmamak daha güvenlidir:
Pattern pattern = Pattern.compile("^.+@.+\\..+$");
Matcher matcher = pattern.matcher(email);
Soruya geç, burada, ama: Bu adreste bir sınıfım var: http://lacinato.com/cm/software/emailrelated/emailaddress
Les Hazlewood'un sınıfına dayanıyor, ancak çok sayıda iyileştirme var ve birkaç hata düzeltiyor. Apache lisansı.
Java'daki en yetenekli e-posta ayrıştırıcı olduğuna inanıyorum ve henüz herhangi bir dilde daha yetenekli bir e-posta ayrıştırıcısı görmedim, ancak orada bir tane olabilir. Lexer tarzı bir ayrıştırıcı değil, ancak bazı karmaşık java regex kullanıyor ve bu nedenle olabildiğince verimli değil, ancak şirketim 10 milyardan fazla gerçek dünya adresini ayrıştırdı: kesinlikle yüksek performanslı olarak kullanılabilir durum. Belki yılda bir kez regex yığını taşmasına neden olan bir adrese (uygun şekilde) çarpacaktır, ancak bunlar yüzlerce veya binlerce karakter uzunluğunda çok sayıda tırnak ve parantez ve benzeri olan spam adresleridir.
RFC 2822 ve ilgili spesifikasyonlar e-posta adresleri açısından gerçekten oldukça izin vericidir, bu nedenle böyle bir sınıf çoğu kullanım için aşırıdır. Örneğin, spec, boşluklar ve her şeye göre aşağıdaki adreste geçerli bir adrestir:
"<bob \" (here) " < (hi there) "bob(the man)smith" (hi) @ (there) example.com (hello) > (again)
Hiçbir posta sunucusu buna izin vermez, ancak bu sınıf onu ayrıştırabilir (ve kullanılabilir bir forma yeniden yazabilir).
Mevcut Java e-posta ayrıştırıcı seçeneklerini yeterince dayanıklı bulduk (yani, bazı geçerli adresleri ayrıştıramadı), bu yüzden bu sınıfı oluşturduk.
Kod iyi belgelenmiştir ve belirli e-posta formlarına izin vermek veya izin vermemek için birçok kolay değiştirilebilir seçeneğe sahiptir. Ayrıca, posta kutusu listesi başlıklarını ayrıştırmak / doğrulamak, dönüş yolunu ayrıştırmak / doğrulamak için adresin belirli bölümlerine (sol taraf, sağ taraf, kişisel adlar, yorumlar vb.) Erişmek için birçok yöntem sağlar. (başlıklar arasında benzersizdir) vb.
Yazılan kodun javamail bağımlılığı vardır, ancak sağladığı küçük işlevselliği istemiyorsanız kaldırmak kolaydır.
Sadece neden @Email
Hibernate Validator'ın ek kısıtlamalarından kimsenin gelmediğini merak ediyorum . Doğrulayıcının kendisi EmailValidator
.
Les Hazlewood, Java düzenli ifadeleri kullanarak çok kapsamlı bir RFC 2822 uyumlu e-posta doğrulama sınıfı yazmıştır. Http://www.leshazlewood.com/?p=23 adresinde bulabilirsiniz . Ancak, kapsamlılığı (veya Java RE uygulaması) verimsizliğe yol açar - uzun adresler için ayrıştırma süreleri hakkındaki yorumları okuyun.
Kodun bazılarını Zend_Validator_Email'de taşıdım:
@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();
}
}
Aşağıdaki gibi bir ana bilgisayar adı doğrulayıcısıyla:
@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()]);
}
}
Ve farklı tld'ler için normal ifade desenlerine sahip geçerli bir IDNs.xml (dahil etmek için çok büyük :)
<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>
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));
}
}
Bir e-posta adresinin geçerli olup olmadığını doğrulamak istiyorsanız, VRFY size bir şekilde yol gösterecektir. İntranet adreslerini (dahili siteler için e-posta adreslerini) doğrulamak için yararlı buldum . Ancak internet posta sunucuları için daha az yararlıdır (bu sayfanın üst kısmındaki uyarılara bakın)
Apache müşterilerinin çok sayıda alternatifi olmasına rağmen, uygulamaları en iyi ihtimalle ilkeldir ( Apache müşterilerinin uygulaması gibi ) ve hatta diğer durumlarda ölü olarak yanlıştır.
Ayrıca sözde basit 'kısıtlayıcı olmayan' regex uzak kalmak istiyorum; böyle bir şey yok. Örneğin @ bağlama göre birçok kez izin verilir , gerekli olanın orada olduğunu nereden biliyorsunuz? Basit normal ifade, e-postanın geçerli olması gerekse bile bunu anlamaz. Daha karmaşık her şey hataya açık hale gelir veya hatta gizli performans katilleri içerir . Nasıl böyle bir şey korumak için gidiyoruz bu ?
Fark ettiğim tek kapsamlı RFC uyumlu normal ifade tabanlı doğrulayıcı e-posta-rfc2822-doğrulayıcıdır ve Dragons.java adı verilen 'rafine' normal ifadesiyle . Bununla birlikte, modern ihtiyaçlar için yeterince uygun olmasına rağmen, yalnızca eski RFC-2822 spesifikasyonunu destekler (RFC-5322 , günlük kullanım durumları için zaten kapsam dışı alanlarda güncellenir ).
Ama gerçekten istediğiniz şey, bir dizeyi düzgün bir şekilde ayrıştıran ve RFC dilbilgisine göre bileşen yapısına ayıran bir lexer . EmailValidator4J bu konuda umut vaat ediyor, ancak yine de genç ve sınırlı.
Sahip olduğunuz diğer bir seçenek de Mailgun'un savaşta test edilmiş doğrulama web hizmeti veya Mailboxlayer API'sı gibi bir web hizmetini kullanmaktır (ilk Google sonuçlarını aldınız ). Kesinlikle RFC uyumlu değildir, ancak modern ihtiyaçlar için yeterince iyi çalışır.
Neyi doğrulamak istiyorsun? Email adresi?
E-posta adresi yalnızca biçim uygunluğu açısından kontrol edilebilir. Standarda bakın: RFC2822 . Bunu yapmanın en iyi yolu düzenli bir ifadedir. Bir e-posta göndermeden gerçekten var olup olmadığını asla bilemezsiniz.
Ortak doğrulayıcıyı kontrol ettim. Bir org.apache.commons.validator.EmailValidator sınıfı içerir. İyi bir başlangıç noktası gibi görünüyor.
Mevcut Apache Commons Validator sürümü 1.3.1'dir .
Doğrulayan sınıf org.apache.commons.validator.EmailValidator'dır. Emekli bir Jakarta ORO projesinden olan org.apache.oro.text.perl.Perl5Util için bir ithalatı var .
BTW, 1.4 sürümü olduğunu buldum, işte API belgeleri . On sitesinde şöyle der: ": 2008 05 Mart | Versiyon: Son Yayın 1.4-SNAPSHOT", ama bu son değil. Kendinizi kurmanın tek yolu (ancak bu bir RELEASE değil, bir anlık görüntüdür) ve kullanın veya buradan indirin . Bu, 1.4'ün üç yıldır (2008-2011) final yapılmadığı anlamına geliyor. Bu Apache'nin tarzında değil. Daha iyi bir seçenek arıyorum, ancak çok benimsenen bir seçenek bulamadım. İyi test edilmiş bir şey kullanmak istiyorum, herhangi bir hataya çarpmak istemiyorum.
Uzunluğunu da kontrol etmek isteyebilirsiniz - e-postalar maksimum 254 karakter uzunluğundadır. Apache ortak doğrulayıcısı kullanıyorum ve bunu kontrol etmiyor.
E-posta adresine bir e-posta göndermek ve bir yanıt beklemek zorunda kalmadıkça, mükemmel kütüphaneler veya bunu kendiniz yapmanın yolları yoktur (bu bir seçenek olmayabilir). Buradan http://blog.logichigh.com/2010/09/02/validating-an-e-mail-address/ şeklinde bir öneri kullanarak ve Java'da çalışacak şekilde kodu ayarladım.
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();
}
Bu en iyi yöntemdir:
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()));
}
Kaynaklar: - http://howtodoinjava.com/2014/11/11/java-regex-validate-email-address/
Başka bir seçenek de, Hazırda Bekletme e-posta doğrulayıcısını , ek açıklamayı @Email
kullanarak veya doğrulayıcı sınıfını programlı olarak kullanmaktır:
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);
}
}
Heres pragmatik yaklaşımım, burada sadece RFC'den izin verilen karakterleri kullanarak makul farklı blah @ etki alanı adresleri istiyorum. Adresler önceden küçük harfe dönüştürülmelidir.
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();
}
}