package com.mini.capi.utils; import org.springframework.util.StringUtils; import javax.mail.*; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimeUtility; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; public class MailParseUtils { /** * 解析邮件发件人(名称+地址) */ public static String parseFrom(Message message) throws MessagingException { Address[] froms = message.getFrom(); if (froms == null || froms.length == 0) { return ""; } InternetAddress from = (InternetAddress) froms[0]; String fromName = from.getPersonal(); // 发件人名称(可能为null) String fromAddr = from.getAddress(); // 发件人地址 return StringUtils.hasText(fromName) ? fromName + "<" + fromAddr + ">" : fromAddr; } /** * 解析邮件收件人(多个用逗号分隔) */ public static String parseTo(Message message) throws MessagingException { return parseRecipients(message, Message.RecipientType.TO); } /** * 解析邮件抄送人(多个用逗号分隔) */ public static String parseCc(Message message) throws MessagingException { return parseRecipients(message, Message.RecipientType.CC); } /** * 通用解析收件人/抄送人 */ private static String parseRecipients(Message message, Message.RecipientType type) throws MessagingException { Address[] recipients = message.getRecipients(type); if (recipients == null || recipients.length == 0) { return ""; } List addrList = new ArrayList<>(); for (Address addr : recipients) { InternetAddress internetAddr = (InternetAddress) addr; String name = internetAddr.getPersonal(); String address = internetAddr.getAddress(); addrList.add(StringUtils.hasText(name) ? name + "<" + address + ">" : address); } return String.join(",", addrList); } /** * 解析邮件内容(支持文本/HTML) */ public static String parseContent(Part part) throws MessagingException, IOException { if (part.isMimeType("text/plain") || part.isMimeType("text/html")) { // 文本/HTML直接读取 return (String) part.getContent(); } // 多部分内容(含附件),递归解析文本部分 if (part.isMimeType("multipart/*")) { MimeMultipart multipart = (MimeMultipart) part.getContent(); for (int i = 0; i < multipart.getCount(); i++) { BodyPart bodyPart = multipart.getBodyPart(i); String content = parseContent(bodyPart); if (StringUtils.hasText(content)) { return content; } } } return ""; } /** * 提取邮件附件(返回附件流+原始文件名) */ public static List extractAttachments(Part part) throws MessagingException, IOException { List attachments = new ArrayList<>(); // 多部分内容才可能有附件 if (part.isMimeType("multipart/*")) { MimeMultipart multipart = (MimeMultipart) part.getContent(); for (int i = 0; i < multipart.getCount(); i++) { BodyPart bodyPart = multipart.getBodyPart(i); // 判断是否为附件(Disposition为ATTACHMENT或INLINE) String disposition = bodyPart.getDisposition(); if (disposition != null && (disposition.equals(Part.ATTACHMENT) || disposition.equals(Part.INLINE))) { // 获取原始文件名(处理中文乱码) String originalFileName = MimeUtility.decodeText(bodyPart.getFileName()); // 获取附件输入流 InputStream inputStream = bodyPart.getInputStream(); attachments.add(new AttachmentInfo(originalFileName, inputStream)); } else { // 递归处理嵌套的多部分内容 attachments.addAll(extractAttachments(bodyPart)); } } } return attachments; } /** * 附件信息封装(原始文件名+输入流) */ public static class AttachmentInfo { private String originalFileName; private InputStream inputStream; public AttachmentInfo(String originalFileName, InputStream inputStream) { this.originalFileName = originalFileName; this.inputStream = inputStream; } // Getter public String getOriginalFileName() { return originalFileName; } public InputStream getInputStream() { return inputStream; } } }