JavaMail 邮件附件名乱码问题

问题:

用JavaMail 发邮件,带上附件,附件名有时乱码,有时非乱码。查看Java端代码:

最终生成的邮件附件名称为:

=UTF-8Q=E6=97=A0=E5=BF=A7Hour=E6=8A=A5=E8=A1=A8=E7=BB=9F=E8=AE=A1.xlsx=

 根据网上部分百度结果修改:

        在设置邮件附件的时候调用javax.mail.internet.MimeUtility 来编码,代码修改如下:

DataSource source = new FileDataSource(filePath);                   

bodyPart = new MimeBodyPart(); 

bodyPart.setDataHandler(new DataHandler(source)); 

bodyPart.setFileName(MimeUtility.encodeText(fileName)); 

multiPart.addBodyPart(bodyPart); 

生成的邮件附件名称为:

=UTF-8Q=E6=97=A0=E5=BF=A7Hour=E6=8A=A5= =UTF-8Q=E8=A1=A8=E7=BB=9F=E8=AE=A1=2Exlsx=

仍旧没有解决乱码问题。

来看邮件源码:

Content-Type: application/octet-stream;
    name*0="=?utf-8?B?5rWL6K+V5qCH6aKYLS0tMDAx5oiR6KaB5LiK?==?utf-8?B?5";
    name*1="a2mQUJDREXvvIzlkKzor7TopoHotrPlpJ/plb8=?=.xlsx"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
    filename*0="?utf-8?B?5rWL6K+V5qCH6aKYLS0tMDAx5oiR6KaB5LiK?==?utf-8?B?5";
    filename*1="a2mQUJDREXvvIzlkKzor7TopoHotrPlpJ/plb8=?=.xlsx"

这串就是 有些系统乱码有些系统 正常显示的 邮件源码。。

对比在邮件客户端上的非乱码邮件:

Content-Type: application/octet-stream; name="=?utf-8?B?5rWL6K+V?=.xlsx"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="=?utf-8?B?5rWL6K+V?=.xlsx"

 filename*0,filename*1 和 filename 的区别,猜测也许就是邮件客户端不支持这种filename*0,filename*1 协议导致的问题。

分析

  有了以上的想法,就开始来看源码。

   MimeBodyPart 这个类中的 setFileName 方法 用到一个 ParameterList 在ParameterList 的 toString 类中找到下面一段:

if (v instanceof MultiValue) {

// ....

ns = name + i + "*";

//...

}

} else if (v instanceof Value) {

/// ...

} else {

if (value.length() > 60 &&

splitLongParameters && encodeParameters) {

int seg = 0;

name += "*";

/// ....

}

这个类在邮件附件属于 MultiValue 会把 名字用name + i 隔开 ,在名字大于 60个字符的时候也会主动截断,这也就是 javamail 中 附件的命名规则,名字太长会被截断~~!

中文在base64 加密后,超过60个字符那是妥妥的有可能。这种截断文件名的模式在某些客户端,并不能很好的支持。

解决

  解决就很容易了, 代码里有 splitLongParameters 这个参数, 观察了下 对应于一个环境变量,如果想不截断文件名,只要在程序运行之初加上:

System.setProperty("mail.mime.splitlongparameters","false");

 正常生产的附件名称为:

         无忧Hour报表统计.xlsx

至此乱码问题解决

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值