How to use javax.mail.internet.MimeBodyPart.setFileName to keep all characters?

折月煮酒 提交于 2020-04-16 12:47:26

问题


I need to create mails using javax.mail version 1.6.2 and would like to stick to high level methods as much as possible and would like to avoid dealing myself with character encoding, folding and whatever is necessary to get a valid mail in the end.

One problem I'm currently dealing with is file names, because by default javax.mail.internet.MimeBodyPart.setFileName seems to encode any given name in a way that my mail client shows it differently than expected. Consider the following name forwarded in a call to setFileName without any custom encoding or else:

meter_cnt_some_month_summary äöüßÄÖÜ.xml

The result looks the following in the generated mail:

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

While that looks OK at first, my mail client renders the _ as space:

And my mail client seems to be right with this decision according to RFC 2047:

(2) The 8-bit hexadecimal value 20 (e.g., ISO-8859-1 SPACE) may be represented as "_" (underscore, ASCII 95.).[...]Note that the "_" always represents hexadecimal 20, even if the SPACE character occupies a different code position in the character set in use.

Support for RFC 2047 has only been added recently to the package and can be disabled by setting a special system property to FALSE. But that doesn't solve the problem, because this only results in UTF-8-bytes in the header which the client can't make much use of.

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"

What I need to do instead is set the system property like above AND additionally take care of encoding the file name myself. But this is exactly what I hoped to avoid.

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?="

So, is RFC 2047 capable of transferring file names containing underscores at all?

I guess it is by simply encoding the underscores themself, leaving only spaces being replaced with underscores for some reason. OTOH, if javax.mail doesn't support it, it might be a known limitation.

Or am I doing something wrong and need to provide the file name differently as well?

Tried to replace _ myself with e.g. =5F, but that didn't work as well. So the only solution I have to be able to transfer file names 1:1 is the workaround above. Which shouldn't be necessary in my opinion or at least the default behaviour if RFC 2047 is really that limited.

Or what am I missing here?

来源:https://stackoverflow.com/questions/60975077/how-to-use-javax-mail-internet-mimebodypart-setfilename-to-keep-all-characters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!