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

JavaMail 實戰:從簡單文本到帶圖片附件的郵件發送完整代碼

     編輯:Java 相關知識

環境準備

  1. 本地搭建郵件服務器(如 Eyou Mail Server)
  2. 創建域名 itcast.com 及賬號 zhangsan@itcast.com、lisi@itcast.com
  3. Foxmail 配置:SMTP/POP3 均指向 localhost,端口 25/110
  4. 引入依賴:mail.jar(核心)、activation.jar(JDK 1.6+ 可省略)
  5. 關鍵:Web 項目中需刪除 Java EE 自帶的 mail.jar,避免衝突

核心類結構

  • Session:郵件會話,持有協議、主機、端口、認證等配置
  • MimeMessage:完整郵件對象(主題、發件人、收件人、時間、內容)
  • Transport:發送器,連接 SMTP 服務器並發送
  • MimeMultipart:容器,組合文本、圖片、附件(子類型:mixed/related/alternative)
  • MimeBodyPart:郵件部件(文本、圖片、附件)
  • DataHandler + DataSource:封裝二進制數據(圖片/附件)

場景一:純文本郵件

Properties prop = new Properties();
prop.put("mail.transport.protocol", "smtp");
prop.put("mail.smtp.host", "localhost");
prop.put("mail.smtp.port", "25");
prop.put("mail.smtp.auth", "true");
prop.put("mail.debug", "true");

Session session = Session.getDefaultInstance(prop);
MimeMessage msg = new MimeMessage(session);
msg.setSubject("第一封郵件");
msg.setSentDate(new Date());
msg.setSender(new InternetAddress("zhangsan@itcast.com"));
msg.setRecipient(RecipientType.TO, new InternetAddress("lisi@itcast.com"));
msg.setText("你好,發送成功!");

Transport trans = session.getTransport();
trans.connect("zhangsan", "888");
trans.sendMessage(msg, msg.getAllRecipients());
trans.close();

場景二:內嵌圖片(HTML 郵件)

關鍵:multipart/related,圖片通過 Content-ID 引用,HTML 用 <img src='cid:xxx'>。

MimeMultipart related = new MimeMultipart("related");

// 文本部分
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent("<img src='cid:8.jpg'/> 好哈哈!", "text/html;charset=UTF-8");

// 圖片部分
MimeBodyPart imgPart = new MimeBodyPart();
DataSource ds = new FileDataSource(new File("path/8.jpg"));
imgPart.setDataHandler(new DataHandler(ds));
imgPart.setContentID("8.jpg"); // 對應 cid:8.jpg

related.addBodyPart(textPart);
related.addBodyPart(imgPart);
message.setContent(related);

場景三:圖片 + 附件(混合郵件)

結構:multipart/mixed 包含兩部分:

  • Left:multipart/related(文本 + 內嵌圖片)
  • Right:MimeBodyPart(附件,setFileName)
MimeMultipart mixed = new MimeMultipart("mixed");
message.setContent(mixed);

// Left
MimeBodyPart left = new MimeBodyPart();
MimeMultipart related = new MimeMultipart("related");
left.setContent(related);
// ... 向 related 添加 textPart、imgPart(同上)

// Right
MimeBodyPart right = new MimeBodyPart();
DataSource ds = new FileDataSource(new File("path/a.docx"));
right.setDataHandler(new DataHandler(ds));
right.setFileName("a.docx"); // 顯示的附件名

mixed.addBodyPart(left);
mixed.addBodyPart(right);

常見問題與最佳實踐

  1. 中文附件名亂碼:MimeUtility.encodeText(fileName, "UTF-8", "B") 編碼後再 setFileName。
  2. 圖片不顯示:檢查 Content-ID 與 cid: 是否一致;路徑獲取用 Class.getResource() 需注意打包後路徑。
  3. 大附件發送失敗:調大 SMTP 服務器限制;考慮分片或雲存儲下載鏈接替代附件。
  4. 連接超時:設置 mail.smtp.connectiontimeout、mail.smtp.timeout(毫秒)。
  5. SSL/TLS:QQ/163 等公共郵箱需 SSL,配置 mail.smtp.ssl.enable=true、端口 465/587,並用 SSLSocketFactory。
  6. 異步發送:生產環境建議放入消息隊列(RabbitMQ/Kafka),由消費者異步發送,避免阻塞業務線程。

總結

JavaMail API 雖然底層,但掌握 MimeMultipart 的三種子類型組合規則(mixed 並列、related 內嵌、alternative 替代),即可構建任意複雜度的郵件。配合 Spring 的 JavaMailSender 封裝,開發體驗更佳。

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