javax.mail 1.5.5中mimePart.getFileName()返回截断文件名的解决方法
解决javax.mail 1.5.5获取分段附件文件名截断问题
问题原因
场景1中邮件头使用了RFC 2231标准的分段式参数(filename*0、filename*1),将长文件名拆分为多个部分存储,但javax.mail 1.5.5版本的mimePart.getFileName()方法未实现该标准的解析逻辑,仅返回第一分段内容,导致文件名截断。
解决方案
方案1:手动解析MIME头拼接完整文件名
如果无法升级javax.mail版本,可直接解析Content-Disposition头的原始内容,手动拼接分段的文件名参数:
import javax.mail.MimePart; import java.util.Map; import java.util.TreeMap; public String getFullFileName(MimePart mimePart) throws Exception { // 获取Content-Disposition头的原始字符串 String disposition = mimePart.getHeader("Content-Disposition", null); if (disposition == null) { return mimePart.getFileName(); } Map<Integer, String> filenameSegments = new TreeMap<>(); String[] headerParts = disposition.split(";"); for (String part : headerParts) { part = part.trim(); if (part.startsWith("filename*")) { int equalsIndex = part.indexOf('='); if (equalsIndex == -1) continue; String paramKey = part.substring(0, equalsIndex); String paramValue = part.substring(equalsIndex + 1).trim(); // 去除首尾引号(如果存在) if (paramValue.startsWith("\"") && paramValue.endsWith("\"")) { paramValue = paramValue.substring(1, paramValue.length() - 1); } // 提取分段序号(如filename*0中的0) int segmentNum = Integer.parseInt(paramKey.substring("filename*".length())); filenameSegments.put(segmentNum, paramValue); } } if (!filenameSegments.isEmpty()) { StringBuilder fullName = new StringBuilder(); for (String segment : filenameSegments.values()) { fullName.append(segment); } return fullName.toString(); } else { // 无分段时回退到原有方法 return mimePart.getFileName(); } }
方案2:升级javax.mail版本
javax.mail 1.6.x及以上版本已修复RFC 2231分段参数的解析问题,升级后直接调用mimePart.getFileName()即可获取完整文件名。例如在Maven中替换依赖:
<dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> <version>1.6.2</version> </dependency>
内容的提问来源于stack exchange,提问作者Dinesh
相关产品推荐
相关产品推荐

