Java Mail 附件名太长导致接收端附件名解析出错

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,会截断附件名

0x05PS

这是 RFC2231 的规定,估计国内的还不支持(个人猜想)

 

0x06(走过的弯路)

之前没头绪。以为是 Linux 的限制;也怀疑过“MimeUtility.encodeWord(name)”的问题。

跟踪源码的时候看错了 jar 包,应该是 com.sun.mail:javax.mail:1.5.6,还不是 javax.mail:mail:1.4.5

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值