132 lines
4.9 KiB
Java
132 lines
4.9 KiB
Java
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<String> 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<AttachmentInfo> extractAttachments(Part part) throws MessagingException, IOException {
|
||
List<AttachmentInfo> 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;
|
||
}
|
||
}
|
||
} |