javax.mail 如何正确解码 UTF-8 附件文件名?
数据阿明
结论
part.getFileName() 返回的文件名可能仍是 MIME 编码格式。先用 MimeUtility.decodeText() 解码,再判断扩展名并保存附件。例如,=?utf-8?Q?Sz=C3=A1mla.docx?= 会被解码为 Számla.docx。
修改代码
导入 MimeUtility:
import javax.mail.internet.MimeUtility;
处理附件时,先解码文件名:
String encodedFileName = part.getFileName();
if (encodedFileName == null) {
continue;
}
String fileName = MimeUtility.decodeText(encodedFileName);
String fullName = AnalyzeEmailsApp.getUserDir() + File.separator + fileName;
把这段逻辑放在 isFileExtension(fileName, ...) 和 part.saveFile(fullName) 之前。MimeUtility.decodeText() 可以处理示例中的 MIME encoded-word;如果文件名已经是普通文本,解码后的结果也可以直接使用。
decodeText() 可能抛出 UnsupportedEncodingException,该异常属于 IOException。问题中的方法签名已经声明了相应的异常类型。若要缩小方法签名,可以单独捕获该异常,并决定解码失败时如何处理。
另一种配置方式
部分 JavaMail 版本支持系统属性 mail.mime.decodefilename。将它设为 true 后,getFileName() 可以自动解码文件名。请在解析邮件前设置该属性,并确认当前使用的 JavaMail 版本支持它。显式调用 MimeUtility.decodeText(),则能直接看出代码在哪里解码文件名。
注意事项
示例将邮件中的文件名直接拼接到本地路径。保存附件前,应限制文件名只包含预期的文件名部分,避免路径分隔符让附件写入目标目录之外。
备注:内容仅供参考。
