如何使用java验证电子邮件地址?

Posted

技术标签:

【中文标题】如何使用java验证电子邮件地址?【英文标题】:How to validate Email Address using java? 【发布时间】:2019-09-17 03:54:54 【问题描述】:

我正在开发一个系统,任何用户都可以在其中发送他的个人信息,例如姓名、联系电话和电子邮件。将有另一个门户,我们可以从中检索这些数据和处理。在这方面,我正在使用 Java Web 技术。

现在我的问题是关于验证电子邮件地址的过程。这不仅意味着电子邮件地址是否格式错误,还意味着该电子邮件 ID 的可用性。

这意味着如果我输入“abc@efg.hijk”,这是完全格式正确的电子邮件ID,但我的系统会检查这样的电子邮件地址是否真的存在。如果存在,我会将其存储在数据库中。

提前感谢您的支持。

【问题讨论】:

What is the best Java email address validation method?的可能重复 @GeorgeZ。我认为您发布的答案仅涉及格式检查 “该电子邮件ID 的可用性” 的唯一检查是发送电子邮件并要求人们单击确认链接或输入验证码。其他任何内容要么过于宽泛,要么过于局限。 ux.stackexchange.com/q/70157/126567 看看这个 【参考方案1】:

电子邮件验证可以通过我从here 找到的“SMTPMXLookup”类来完成。以下类可以帮助您查找电子邮件地址的有效性:

public class SMTPMXLookup 

    private static int hear(BufferedReader in) throws IOException 
        String line = null;
        int res = 0;

        while ((line = in.readLine()) != null) 
            String pfx = line.substring(0, 3);
            try 
                res = Integer.parseInt(pfx);
             catch (Exception ex) 
                res = -1;
            
            if (line.charAt(3) != '-') 
                break;
            
        

        return res;
    

    private static void say(BufferedWriter wr, String text)
            throws IOException 
        wr.write(text + "\r\n");
        wr.flush();

        
    
    
    private static ArrayList getMX( String hostName )
         throws NamingException 
     // Perform a DNS lookup for MX records in the domain
     Hashtable env = new Hashtable();
     env.put("java.naming.factory.initial",
             "com.sun.jndi.dns.DnsContextFactory");
     DirContext ictx = new InitialDirContext( env );
     Attributes attrs = (Attributes) ictx.getAttributes( hostName, new String[]  "MX" );
     Attribute attr = attrs.get( "MX" );

     // if we don't have an MX record, try the machine itself
     if (( attr == null ) || ( attr.size() == 0 )) 
       attrs = ictx.getAttributes( hostName, new String[]  "A" );
       attr = attrs.get( "A" );
       if( attr == null )
            throw new NamingException
                     ( "No match for name '" + hostName + "'" );
     
         // Huzzah! we have machines to try. Return them as an array list
     // NOTE: We SHOULD take the preference into account to be absolutely
     //   correct. This is left as an exercise for anyone who cares.
     ArrayList res = new ArrayList();
     NamingEnumeration en = attr.getAll();

     while ( en.hasMore() ) 
        String mailhost;
        String x = (String) en.next();
        String f[] = x.split( " " );
        //  THE fix *************
        if (f.length == 1)
            mailhost = f[0];
        else if ( f[1].endsWith( "." ) )
            mailhost = f[1].substring( 0, (f[1].length() - 1));
        else
            mailhost = f[1];
        //  THE fix *************            
        res.add( mailhost );
     
     return res;
     
    
    public static boolean isAddressValid( String address ) 
     // Find the separator for the domain name
     int pos = address.indexOf( '@' );

     // If the address does not contain an '@', it's not valid
     if ( pos == -1 ) return false;

     // Isolate the domain/machine name and get a list of mail exchangers
     String domain = address.substring( ++pos );
     ArrayList mxList = null;
     try 
        mxList = getMX( domain );
     
     catch (NamingException ex) 
        return false;
     

     // Just because we can send mail to the domain, doesn't mean that the
     // address is valid, but if we can't, it's a sure sign that it isn't
     if ( mxList.size() == 0 ) return false;

     // Now, do the SMTP validation, try each mail exchanger until we get
     // a positive acceptance. It *MAY* be possible for one MX to allow
     // a message [store and forwarder for example] and another [like
     // the actual mail server] to reject it. This is why we REALLY ought
     // to take the preference into account.
     for ( int mx = 0 ; mx < mxList.size() ; mx++ ) 
         boolean valid = false;
         try 
             int res;
             //
             Socket skt = new Socket( (String) mxList.get( mx ), 25 );
             BufferedReader rdr = new BufferedReader
                ( new InputStreamReader( skt.getInputStream() ) );
             BufferedWriter wtr = new BufferedWriter
                ( new OutputStreamWriter( skt.getOutputStream() ) );

             res = hear( rdr );
             if ( res != 220 ) throw new Exception( "Invalid header" );
             say( wtr, "EHLO rgagnon.com" );

             res = hear( rdr );
             if ( res != 250 ) throw new Exception( "Not ESMTP" );

             // validate the sender address              
             say( wtr, "MAIL FROM: <tim@orbaker.com>" );
             res = hear( rdr );
             if ( res != 250 ) throw new Exception( "Sender rejected" );

             say( wtr, "RCPT TO: <" + address + ">" );
             res = hear( rdr );

             // be polite
             say( wtr, "RSET" ); hear( rdr );
             say( wtr, "QUIT" ); hear( rdr );
             if ( res != 250 )
                throw new Exception( "Address is not valid!" );

             valid = true;
             rdr.close();
             wtr.close();
             skt.close();
         
         catch (Exception ex) 
           // Do nothing but try next host
           ex.printStackTrace();
         
         finally 
           if ( valid ) return true;
         
     
     return false;
     

    
    

【讨论】:

【参考方案2】:

您可以轻松地在 Google 上搜索格式检查代码。因此,我们只讨论存在性检查过程。

    格式检查后,生成验证码并保存。 将代码发送到您的目标电子邮件。 用户填写代码,然后进行比较。 存储电子邮件地址。

【讨论】:

以上是关于如何使用java验证电子邮件地址?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 php 验证电子邮件地址? [复制]

如何使用 smtplib 在 Python 中验证电子邮件地址

如何使用 email_validator 验证电子邮件地址

Symfony2 - 如何验证控制器中的电子邮件地址

不使用正则表达式的 Java 电子邮件验证

如何使用 Python 验证电子邮件地址