首页 > 解决方案 > 如何使用 javax.mail.internet.MimeBodyPart.setFileName 保留所有字符?

问题描述

我需要使用javax.mail1.6.2 版创建邮件,并希望尽可能坚持高级方法,并希望避免处理字符编码、折叠以及最终获得有效邮件所需的任何事情。

我目前正在处理的一个问题是文件名,因为默认情况下javax.mail.internet.MimeBodyPart.setFileName似乎以我的邮件客户端显示它的方式与预期不同的方式对任何给定名称进行编码。setFileName考虑在没有任何自定义编码的情况下在调用中转发以下名称:

meter_cnt_some_month_summary äöüßÄÖÜ.xml

结果在生成的邮件中如下所示:

Content-Type: application/xml; charset=UTF-8; 
    name*=UTF-8''meter_cnt_some_month_summary%20%C3%A4%C3%B6%C3%BC%C3%9F%C3%84%C3%96%C3%9C.xml
Content-Disposition: attachment; 
    filename*=UTF-8''meter_cnt_some_month_summary%20%C3%A4%C3%B6%C3%BC%C3%9F%C3%84%C3%96%C3%9C.xml

虽然起初看起来不错,但我的邮件客户端将_空间呈现为:

邮件客户端截图

根据RFC 2047 ,我的邮件客户端似乎对这个决定是正确的:

(2) 8 位十六进制值 20(例如,ISO-8859-1 SPACE)可以表示为“_”(下划线,ASCII 95。)。[...]请注意,“_”始终表示十六进制 20 , 即使 SPACE 字符在使用的字符集中占据不同的代码位置。

对 的支持RFC 2047仅在最近才添加到包中,可以通过将特殊系统属性设置为 来禁用FALSE。但这并不能解决问题,因为这只会导致客户端无法充分利用标头中的 UTF-8 字节。

System.setProperty("mail.mime.encodeparameters", Boolean.FALSE.toString())

Content-Type: application/xml; charset=UTF-8; 
    name="meter_cnt_some_month_summary äöüßÄÖÜ.xml"
Content-Disposition: attachment; 
    filename="meter_cnt_some_month_summary äöüßÄÖÜ.xml"

邮件客户端截图

我需要做的是像上面一样设置系统属性,另外还要自己编码文件名。但这正是我希望避免的。

name = MimeUtility.encodeText(name, "UTF-8", "Q");

Content-Type: application/xml; charset=UTF-8; 
    name="=?UTF-8?Q?meter=5Fcnt=5Fsome=5Fmonth?=
 =?UTF-8?Q?=5Fsummary_=C3=A4=C3=B6=C3=BC=C3=9F=C3=84=C3=96=C3=9C.xml?="
Content-Disposition: attachment; 
    filename="=?UTF-8?Q?meter=5Fcnt=5Fsome=5Fmonth?=
 =?UTF-8?Q?=5Fsummary_=C3=A4=C3=B6=C3=BC=C3=9F=C3=84=C3=96=C3=9C.xml?="

邮件客户端截图

那么,是否RFC 2047能够传输包含下划线的文件名?

我想这是通过简单地自己编码下划线,只留下空格被下划线替换出于某种原因。OTOH,如果javax.mail不支持它,它可能是一个已知的限制。

还是我做错了什么并且需要以不同的方式提供文件名?

试图_用 eg 替换自己=5F,但效果不佳。因此,我必须能够 1:1 传输文件名的唯一解决方案是上面的解决方法。在我看来,这不应该是必要的,或者至少是默认行为,如果RFC 2047真的那么有限的话。

或者我在这里错过了什么?

标签: javaemailjakarta-mailrfc822

解决方案


推荐阅读