0x00(測試條件)
附件名:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt
0x01(現象)
新浪郵箱解析出錯:
QQ郵箱解析出錯:
0x02(分析問題)
本地沒問題,到 Linux 環境纔出錯。所以抓了本地的包和 Linux 下的包比較。
本地的包(之前用比較長的中文名測試抓的包):
------=_Part_18_1324418920.1488440125843
Content-Type: application/octet-stream;
name="=?UTF-8?Q?=E4=B8=AD=E6=96=87=E5=AD=97=E7=AC=A6201711=2Edocx?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="=?UTF-8?Q?=E4=B8=AD=E6=96=87=E5=AD=97=E7=AC=A6201711=2Edocx?="
Linux 的包:
------=_Part_0_528597028.1488450122516
Content-Type: text/plain; charset=us-ascii;
name*0=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
name*1=a.txt
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename*0=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
filename*1=a.txt
可以看到問題是文件名太長被拆分了0x03(查找根源)
看 Java 代碼
String encodeName = MimeUtility.encodeWord(name); UrlResource inputStreamSource = new UrlResource(attach.getUrl()); helper.addAttachment(encodeName, inputStreamSource); // 自己的業務代碼
addAttachment(attachmentFilename, inputStreamSource, contentType); // 跟進去
addAttachment(attachmentFilename, dataSource); // 跟進去
mimeBodyPart.setFileName(MimeUtility.encodeText(attachmentFilename)); // 跟進去
setFileName(this, filename); // 跟進去
part.setHeader("Content-Disposition", cd.toString()); // 跟進去
sb.append(list.toString(sb.length() + 21)); // 跟進去
if (value.length() > 60 && splitLongParameters && encodeParameters) { int seg = 0; name += "*"; // 省略...
已經看出是怎麼回事了
0x04(解決)
在 Main方法下加
System.setProperty("mail.mime.splitlongparameters", "false"); // linux 會默認爲 true,會截斷附件名
0x05(PS)
這是 RFC2231 的規定,估計國內的還不支持(個人猜想)
0x06(走過的彎路)
之前沒頭緒。以爲是 Linux 的限制;也懷疑過“MimeUtility.encodeWord(name)”的問題。
跟蹤源碼的時候看錯了 jar 包,應該是 com.sun.mail:javax.mail:1.5.6,還不是 javax.mail:mail:1.4.5