業務系統常需發送格式複雜的郵件(HTML 排版、內嵌圖片、附件、多收件人)。若在程式碼中手工構建 MimeMessage,程式碼冗長且難維護。本文介紹一種「所見即所得」方案:先用 Outlook 編寫郵件存為 .eml,再由 Java 直接發送。
import java.io.FileInputStream;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
public class SendOutlookEmail {
public static void main(String[] args) throws Exception {
// 1. 郵件伺服器配置
Properties props = new Properties();
props.setProperty("mail.smtp.auth", "true");
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", "smtp.sina.com"); // 替換為實際 SMTP
// 2. 建立帶認證的 Session
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("your_account", "your_password");
}
});
session.setDebug(true); // 開啟除錯輸出
// 3. 直接載入 Outlook 儲存的 .eml 檔案
Message msg = new MimeMessage(session,
new FileInputStream("resource/demo3.eml"));
// 4. 發送(收件人已包含在 EML 中,亦可程式指定)
Transport.send(msg, InternetAddress.parse("recipient@example.com"));
}
}
.msg,需先轉換為 .eml(Outlook 拖曳到資料夾自動轉換,或用工具).eml 放入專案資源目錄(如 src/main/resources/emails/)若需在固定模板中插入動態內容(如用戶名、驗證碼),可採用模板引擎:
// 讀取 EML 為字串
String emlContent = new String(Files.readAllBytes(Paths.get("template.eml")), "UTF-8");
// 簡單佔位符替換(生產建議用 FreeMarker/Thymeleaf)
emlContent = emlContent.replace("${username}", "張三")
.replace("${code}", "123456");
// 解析為 MimeMessage
MimeMessage msg = new MimeMessage(session,
new ByteArrayInputStream(emlContent.getBytes("UTF-8")));
| 優點 | 缺點/注意事項 |
|---|---|
| 業務與樣式分離,美工可直接維護樣板 | 動態內容處理需額外模板引擎支援 |
| 程式碼極度簡化,減少 MimeMessage 構建錯誤 | EML 相對路徑部署需注意(建議用 classpath 載入) |
| 所見即所得,避免 HTML 相容性調試 | 大量發送時 IO 開銷較大,建議快取 MimeMessage |
| 支援複雜結構:內嵌圖片、多附件、替代文本 | Outlook 產生的 EML 可能含專有標頭,需測試相容性 |
getClass().getResourceAsStream("/emails/template.eml") 替代檔案路徑mail.smtp.connectionpool 或使用 Spring Mail 整合@Async 或訊息佇列避免阻塞業務線程「Outlook 編寫 + Java 發送 EML」是處理複雜郵件場景的實用折中方案:發揮圖形化工具優勢設計樣板,利用 JavaMail 標準 API 可靠投遞。配合模板引擎實現動態化,可大幅降低郵件開發維護成本。