【问题标题】:Email Validation RFC 2821 using Java使用 Java 的电子邮件验证 RFC 2821
【发布时间】:2023-04-10 15:08:01
【问题描述】:

我正在使用考虑到 RFC 2821 的 java 进行电子邮件验证。 我使用以下代码验证了我所有的电子邮件地址:

InternetAddress emailAddr = new InternetAddress(email);
emailAddr.validate();

Java api 表示其符合 RFC-822。 RFC 2821 和 822 有很大区别吗?

在以下情况下,上述 api 也无法验证电子邮件:

  1. var@yahoo - 验证返回 true,但它是无效的电子邮件
  2. var(comment)@yahoo.com - 验证返回 false,但它是有效的电子邮件

你能告诉我任何解决方法来完成它吗?

【问题讨论】:

  • 您确定ar@yahoo 应该无效吗?我会检查一个通用顶级域是否可以用作主机名。
  • 文档说:“验证地址部分”所以我猜@ 之后的所有内容都会被忽略。
  • 在之前的问题中,Apache Commons 被建议为最佳工具 (stackoverflow.com/questions/624581/…),但我刚刚尝试过,它也无法接受 cmets。

标签: email-validation jakarta-mail rfc822 rfc2822


【解决方案1】:

现代电子邮件地址的处理方式与原始标准中的电子邮件地址存在重大差异。

根据我设置 dns 和绑定地址的经验,您可以指定一个不带句点的域名,但是当查询解析器时,它会将. 添加到域名的末尾。您还可以在主机文件中指定直接映射。大多数主机文件包含这样的解析本地主机:

127.0.0.1 本地主机环回

意味着如果您在带有邮件服务器的服务器上,您可以向user@localhost 发送有效的电子邮件。

根据RFC 822:

在正式注册的情况下,组织实施 (分布式)数据库,提供地址到路由的映射 表格地址的服务:

            person@registry.organization

请注意,“组织”是一个逻辑实体,独立于任何 特定的通信网络。

访问“组织”的机制是普遍可用的。
反过来,该机制寻求注册表的实例化;它的 地址说明中未指明位置。它是 假设以“组织”名义运行的系统 知道如何找到从属注册表。然后注册表将 使用“person”字符串来确定将邮件发送到哪里 规范。

后一种面向网络的案例允许简单、直接、 附件相关的地址规范,如:

                 user@host.network

对于本地系统上的user@host.network,只要电子邮件系统配置正确,您就可以向user@host 发送电子邮件。尽管这不是我们现在习惯的FQDN - Fully Qualified Domain Name,但该标准直到很久以后才出现。然后,邮件系统使用别名将其发送到正确的本地网络,将电子邮件转换为user@host.network。电子邮件欺骗的问题直到后来 ARPAnet 公开后才出现。

关于地址中的 cmets,RFC 822 中没有。根据后来允许 cmets (RFC 2822 Section 3.4) 的电子邮件规范:

另外,由于一些旧版实现会解释注释, cmets 通常不应在地址字段中使用以避免 混淆此类实现。

意味着旧系统不允许在地址中使用 cmets。 RFC 822 没有在邮件地址中提及 cmets。

技术解决方法是不允许电子邮件地址中包含 cmets,除非您使用自定义代码来容纳它们。您可以随时更新 Javamail。 Newer implementations accommodate updated RFCs.

【讨论】:

    【解决方案2】:

    在我看来,您想要验证现在使用的电子邮件 ID,而不是真正符合任何 RFC。 对于我们的项目,我们制作了自己的非常简单的电子邮件验证器。为什么 ? apache 和 java 邮件之一使用正则表达式,并且在某些情况下(我不知道是哪一个,因为我们没有在日志中打印电子邮件)使正则表达式进入一个永远循环。这意味着客户端处理程序线程进入循环并且用户看到一个空白屏幕!

    所以我们所做的实际上是允许新的电子邮件 ID 就像它们在 google/yahoo 等网站上的样子。

    含义 somecahrs@xyz.com

    我们检查的内容 最多 1 个@ 在 @ 之前检查 1 个或多个字符 @ 之后有一些字符 + 至少一个点 + 点后的字符

    过去两年没有收到任何投诉。此外,在大多数情况下,您需要向此人发送电子邮件以确保域存在等以及带有唯一令牌的链接(注册确认)以确保此人拥有电子邮件 ID(向真实所有者发送消息仅如果他们来到您的网站,请点击)

        /**
         * minimum email l@n.co
         * */
        public static boolean checkEmail(final String emlId, int dbgPrint) {
            // ex:ak@bv.gh
            if (emlId == null){
                return false;
            }
            final int lngth = emlId.length();
            if (lngth < 6) {
                if (dbgPrint > 1) {
                    System.out.println(" lngth < 6");
                }
                return false;
            }
            final int locationAt = emlId.indexOf('@');
            if (locationAt < 1) {
                if (dbgPrint > 1) {
                    System.out.println("locationAt < 1 : " + locationAt);
                }
                return false;//
            }
            final int postLastPeriod = emlId.lastIndexOf('.');
            if (postLastPeriod < 0) {
                if (dbgPrint > 1) {
                    System.out.println("postLastPeriod < 0, locationAt " + locationAt);
                }
                return false;
            }
            if (dbgPrint > 1) {
                System.out.println(" locationAt " + locationAt + ", postLastPeriod :" + postLastPeriod + " lngth " + lngth);
            }
            if (lngth - postLastPeriod < 3) {
                if (dbgPrint > 1) {
                    System.out.println(" lngth - postLastPeriod < 2");
                }
                return false;
            }
            if (postLastPeriod - locationAt < 1) {
                if (dbgPrint > 1) {
                    System.out.println(" postLastPeriod - locationAt < 1");
                }
                return false;
            }
            return true;
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-28
      • 2014-10-11
      • 2012-10-03
      • 2011-12-01
      • 2016-05-26
      • 2020-02-04
      • 2010-09-14
      相关资源
      最近更新 更多