首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JavaMail實戰指南:從純文本到圖文附件混合郵件完整實現

     編輯:Java 綜合教學

前言:JavaMail核心組件速覽

  • Session:郵件會話環境,持有協議配置、認證信息
  • MimeMessage:MIME郵件對象,承載頭部(From/To/Subject)與內容
  • Transport:傳輸協議實現(SMTP),負責發送
  • MimeMultipart:容器,組合多個BodyPart(文本/圖片/附件)
  • MimeBodyPart:郵件部件,可為文本、圖片、附件或嵌套Multipart

關鍵配置:mail.smtp.auth=true 需授權碼而非登錄密碼;session.setDebug(true) 開啟調試輸出。

場景一:純文本/HTML郵件

Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", "smtp.163.com");
props.setProperty("mail.smtp.auth", "true");

Session session = Session.getInstance(props);
session.setDebug(true);

MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("xxx@163.com"));
message.setRecipients(Message.RecipientType.TO, "xxx@qq.com");
message.setSubject("測試郵件");

// HTML內容
message.setContent("<h1>Hello JavaMail</h1>", "text/html;charset=UTF-8");
// 純文本備選
// message.setText("純文本內容");

message.saveChanges();

Transport ts = session.getTransport();
ts.connect("xxx@163.com", "授權碼"); // 注意:此處為授權碼
ts.sendMessage(message, message.getAllRecipients());

要點:setContent(String, "text/html") 支持富文本;saveChanges() 更新頭部字段(如Message-ID、Date)。

場景二:內嵌圖片郵件

關鍵模型:multipart/related 關聯文本與圖片,圖片通過 Content-ID (cid:) 引用。

復雜郵件封裝模型
// 文本部分
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent("正文內容<img src='cid:imageId'>繼續正文", "text/html;charset=UTF-8");

// 圖片部分
MimeBodyPart imagePart = new MimeBodyPart();
imagePart.setContentID("<imageId>"); // 需包含<>
DataHandler dh = new DataHandler(new FileDataSource("src/logo.png"));
imagePart.setDataHandler(dh);

// 關聯容器
MimeMultipart relatedMp = new MimeMultipart();
relatedMp.addBodyPart(textPart);
relatedMp.addBodyPart(imagePart);
relatedMp.setSubType("related"); // 關鍵:related

message.setContent(relatedMp);

坑點提示:setContentID 值需與HTML中cid:後的標識一致,建議加角括號<id>提高兼容性;需引入JAF (activation.jar) 支持DataHandler。

場景三:文本+圖片+附件混合郵件

分層結構:multipart/mixed (頂層) → [附件Part, multipart/related (文本+圖片)]

// 文本+圖片 關聯層(同上)
MimeMultipart relatedMp = new MimeMultipart();
relatedMp.addBodyPart(textPart);
relatedMp.addBodyPart(imagePart);
relatedMp.setSubType("related");

// 包裝為單一Part
MimeBodyPart textImagePart = new MimeBodyPart();
textImagePart.setContent(relatedMp);

// 附件部分
MimeBodyPart attachPart = new MimeBodyPart();
DataHandler attachDh = new DataHandler(new FileDataSource("src/報表.pdf"));
attachPart.setDataHandler(attachDh);
// 解決中文附件名亂碼
attachPart.setFileName(MimeUtility.encodeText(attachDh.getName()));

// 最終混合容器
MimeMultipart mixedMp = new MimeMultipart();
mixedMp.addBodyPart(attachPart);      // 附件通常在前
mixedMp.addBodyPart(textImagePart);   // 正文在後
mixedMp.setSubType("mixed");

message.setContent(mixedMp);

編碼關鍵:MimeUtility.encodeText(filename) 實現RFC 2047編碼,解決中文附件名在各郵箱客戶端顯示亂碼問題。

常見問題排查清單

現象可能原因解決方案
發送失敗 535 Error授權碼錯誤/未開啟SMTP服務郵箱設定中生成專用授權碼,開啟SMTP/IMAP
圖片不顯示cid不匹配 / Content-ID格式錯誤確保setContentID("") 與HTML中cid:id一致
附件名亂碼未編碼 / 編碼方式不兼容使用MimeUtility.encodeText() 或 MimeUtility.encodeWord()
進垃圾箱內容關鍵詞 / 發信域信譽配置SPF/DKIM/DMARC,優化內容,避免營銷詞彙

總結

JavaMail通過MimeMultipart嵌套組合實現複雜郵件結構:related綁定文本與內嵌資源,mixed混合附件與正文。掌握「容器套容器、Part裝Part」的組合模式,配合正確MIME類型與編碼處理,即可構建企業級郵件發送能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved