【问题标题】:I am losing periods in an email sent using Java Mail我在使用 Java Mail 发送的电子邮件中失去了月经
【发布时间】:2010-09-12 07:05:53
【问题描述】:

我正在从 Java 服务器发送时事通讯,但其中一个超链接到达时缺少句点,使其无用:

Please print your <a href=3D"http://xxxxxxx.xxx.xx.edu=
au//newsletter2/3/InnovExpoInviteVIP.pdf"> VIP invitation</a> for future re=
ference and check the Innovation Expo website <a href=3D"http://xxxxxxx.xx=
xx.xx.edu.au/2008/"> xxxxxxx.xxxx.xx.edu.au</a> for updates.

在上面的示例中,第一个超链接上 edu 和 au 之间的句点丢失了。

我们已经确定邮件正文被换行并且换行在句点处拆分行,并且在 SMTP 电子邮件中以句点开头的行是非法的:

https://www.rfc-editor.org/rfc/rfc2821#section-4.5.2

我的问题是 - 我应该使用什么设置来确保包装是周期友好的和/或首先不执行?

更新:经过 大量 的测试和调试,结果证明我们的代码没问题 - 客户端的 Linux 服务器附带了一个 非常 旧的 Java 版本和旧的邮件类仍在其中一个 lib 文件夹中,并且优先于我们的。 JDK 1.2 之前有这个bug。

【问题讨论】:

    标签: java smtp email


    【解决方案1】:

    从 SMTP 的角度来看,您可以用句点开始一行,但您必须改为发送两个句点。如果您使用的 SMTP 客户端不这样做,您可能会遇到您描述的问题。

    可能值得尝试使用 IP 嗅探器来查看问题的真正所在。发送该电子邮件可能涉及至少两个单独的 SMTP 事务。

    【讨论】:

      【解决方案2】:

      我在 HTML 电子邮件中遇到了类似的问题:神秘的缺失句点,在一种情况下,邮件被奇怪地截断了。 JavaMail 使用带引号的可打印编码发送 HTML 电子邮件,该编码在任何点(即不仅在空白处)换行,因此任何行都不会超过 76 个字符。 (它在行尾使用“=”作为软回车,因此接收者可以重新组合行。)这很容易导致一行以句点开头,应该加倍。 (这称为“点填充”)如果不是,则接收 SMTP 服务器会吃掉句点,或者更糟的是,如果句点是一行中的唯一字符,则 SMTP 服务器会将其解释为消息。

      我追踪到了 GNU JavaMail 1.1.2 实现(又名 classpathx javamail)。此实现没有更新版本,并且已经有 4 或 5 年没有更新了。查看源代码,它部分实现了点填充——它尝试单独处理一行中的句点,但是有一个错误甚至阻止了这种情况的工作。

      不幸的是,这是我们平台(Centos 5)上的默认实现,所以我想它也是 RedHat 上的默认实现。

      Centos 的修复方法是安装 Sun 的(或者我现在应该说 Oracle 的?)JavaMail 实现(我使用的是 1.4.4),并使用 Centos alternatives 命令安装它来代替默认实现。 (使用 alternatives 确保安装 Centos 补丁不会导致恢复到 GNU 实现。)

      【讨论】:

        【解决方案3】:

        通过引用可打印确保您的所有内容都是 RFC2045 友好的。 在这样的方法中使用 MimeUtility 类。

        private String mimeEncode (String input) { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out; try { out = MimeUtility.encode( bOut, "quoted-printable" ); out.write( input.getBytes( ) ); out.flush( ); out.close( ); bOut.close( ); } catch (MessagingException e) { log.error( "Encoding error occured:",e ); return input; } catch (IOException e) { log.error( "Encoding error occured:",e ); return input; } return bOut.toString( ); }

        【讨论】:

          【解决方案4】:

          我遇到了类似的问题,但使用的是 ASP.NET 2.0。根据应用程序日志,电子邮件中的链接是正确的“http://www.3rdmilclassrooms.com/”但是客户端收到的电子邮件链接缺少句点“http://www3rdmilclassrooms.com

          我已尽我所能证明电子邮件是通过正确的链接发送的。我怀疑是电子邮件客户端或垃圾邮件过滤软件正在修改超链接。垃圾邮件过滤软件有可能做到这一点吗?

          【讨论】:

          • .NET 4.0 中存在同样的问题,这是 System.Web.Mail 中的一个错误
          【解决方案5】:

          您是否将 Mime 类型设置为“text/html”?你应该有这样的东西:

          BodyPart bp = new MimeBodyPart();
          bp.setContent(message,"text/html");
          

          【讨论】:

            【解决方案6】:

            我不确定,但它看起来有点像您的电子邮件正在被编码。 0x3D是十六进制字符61,也就是等号('=')。

            您使用什么类/库来发送电子邮件?检查有关编码的设置。

            【讨论】:

              【解决方案7】:

              我在以编程方式向雅虎帐户发送电子邮件时遇到了类似的问题。他们会得到一行很长的文本并在 HTML 电子邮件中添加自己的换行符,认为这不会导致问题,但当然会。

              诀窍是不要尝试发送这么长的线路。因为 HTML 电子邮件不关心换行符,所以您应该每隔几个块添加自己的内容,或者就在有问题的行之前添加自己的内容,以确保您的 URL 在这样的时间段不会被拆分。

              我不得不从

              更改我的 ASP VB
              var html;
              html = "Blah Blah Blah Blah ";
              html = html & " More Text Here....";
              

              var html;
              html = "Blah Blah Blah Blah " & VbCrLf;
              html = html & " More Text Here....";
              

              这就是清理正在处理的输出所需要的全部内容。

              【讨论】:

              • 如果文本是用quoted-printable编码的,这不会有太大帮助,就像问题中提供的示例一样。 Quoted-printable 每行限制为 76 个字符。
              【解决方案8】:

              正如 Greg 指出的,问题出在您的 SMTP 客户端,它不进行点填充(将前导点加倍)。

              似乎电子邮件正在被编码为quoted-printable。切换到 base64(我假设您可以使用当前的 java mime 实现)将解决问题。

              【讨论】:

                猜你喜欢
                • 2020-04-19
                • 2015-09-29
                • 1970-01-01
                • 2015-06-30
                • 1970-01-01
                • 1970-01-01
                • 2020-04-19
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多