浏览代码

fix:邮件附件名称获取重构

wangzaijun 1 月之前
父节点
当前提交
eeffbc9e0c
共有 1 个文件被更改,包括 32 次插入6 次删除
  1. 32 6
      mo-daq/src/main/java/com/smppw/modaq/domain/service/EmailParseService.java

+ 32 - 6
mo-daq/src/main/java/com/smppw/modaq/domain/service/EmailParseService.java

@@ -47,6 +47,7 @@ import org.springframework.util.StopWatch;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.*;
@@ -684,22 +685,23 @@ public class EmailParseService {
 
     private void rePart(String account, String subject, Date sendDate, Part part,
                         List<EmailContentInfoDTO> emailContentInfoDTOList) throws Exception {
-        String fileName = part.getFileName();
+        String fileName = decodeFileName(part);
         if (StrUtil.isBlank(fileName)) {
             log.warn("邮件{} 附件文件名是空的,不做下载!", subject);
             return;
         }
-        fileName = MimeUtility.decodeText(fileName);
         String disposition = part.getDisposition();
         String contentType = part.getContentType();
+        if (log.isInfoEnabled()) {
+            log.info("邮件{} 附件(fileName={},disposition={},contentType={})",
+                    subject, fileName, disposition, contentType);
+        }
         boolean isAttachment =
                 (disposition != null && (disposition.equalsIgnoreCase(Part.ATTACHMENT))) ||
                         StrUtil.startWithIgnoreCase(contentType, MediaType.APPLICATION_PDF.toString());
         if (!isAttachment) {
-            if (log.isInfoEnabled()) {
-                log.info("邮件{} 没有附件(fileName={},disposition={},contentType={}),下载不了附件内容!",
-                        subject, fileName, disposition, contentType);
-            }
+            log.warn("邮件{} 没有附件(fileName={},disposition={},contentType={}),下载不了附件内容!",
+                    subject, fileName, disposition, contentType);
             return;
         }
 
@@ -730,6 +732,30 @@ public class EmailParseService {
         emailContentInfoDTOList.add(emailContentInfoDTO);
     }
 
+    // 解码文件名(处理 RFC 2231 和 RFC 2047)
+    private static String decodeFileName(Part part) throws UnsupportedEncodingException, MessagingException {
+        String filename = part.getFileName();
+
+        // 优先尝试 RFC 2231 的 filename*(如 "filename*=utf-8''%E4%B8%AD%E6%96%87.txt")
+        String[] values = part.getHeader("Content-Disposition");
+        if (values != null) {
+            for (String value : values) {
+                if (value.startsWith("filename*")) {
+                    filename = value.split("'")[2]; // 提取编码后的字符串
+                    filename = MimeUtility.decodeText(filename);
+                    return filename;
+                }
+            }
+        }
+
+        // 处理 RFC 2047 的多段编码(如 "=?utf-8?B?5Lit?= =?utf-8?B?5paH?=.txt")
+        if (filename != null && filename.contains("=?")) {
+            return MimeUtility.decodeText(filename);
+        }
+
+        return filename;
+    }
+
     private void reMultipart(String account, String subject, Date emailDate, Multipart multipart,
                              List<EmailContentInfoDTO> emailContentInfoDTOList) throws Exception {
         for (int i = 0; i < multipart.getCount(); i++) {