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

JavaMail 發送郵件完整實戰:從簡單文本到 HTML 與附件的封裝工具類

     編輯:Java 相關知識

痛點:JavaMail API 繁瑣、樣板代碼多

每次發郵件都要寫 Session、MimeMessage、Transport、Authenticator……為了專注業務,我們將核心邏輯封裝為三個類,打包成 com.util.mail,引用即用。

三大核心類設計

1. 數據載體:MailSenderInfo

package com.util.mail;
import java.util.Properties;

public class MailSenderInfo {
    // 服務器配置
    private String mailServerHost;
    private String mailServerPort = "25";
    // 發件人/收件人
    private String fromAddress;
    private String toAddress;
    // 認證
    private String userName;
    private String password;
    private boolean validate = false;
    // 郵件內容
    private String subject;
    private String content;
    private String[] attachFileNames;  // 附件路徑陣列

    // 產生 JavaMail Session 所需 Properties
    public Properties getProperties() {
        Properties p = new Properties();
        p.put("mail.smtp.host", mailServerHost);
        p.put("mail.smtp.port", mailServerPort);
        p.put("mail.smtp.auth", validate ? "true" : "false");
        return p;
    }
    // ... 所有字段的 getter/setter 省略
}

2. 核心發送器:SimpleMailSender

package com.util.mail;
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

public class SimpleMailSender {

    /** 發送純文本郵件 */
    public boolean sendTextMail(MailSenderInfo mailInfo) {
        Session session = createSession(mailInfo);
        try {
            MimeMessage msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress(mailInfo.getFromAddress()));
            msg.setRecipient(Message.RecipientType.TO, 
                             new InternetAddress(mailInfo.getToAddress()));
            msg.setSubject(mailInfo.getSubject());
            msg.setSentDate(new Date());
            msg.setText(mailInfo.getContent());  // 純文本
            Transport.send(msg);
            return true;
        } catch (MessagingException e) { e.printStackTrace(); return false; }
    }

    /** 發送 HTML 郵件 */
    public static boolean sendHtmlMail(MailSenderInfo mailInfo) {
        Session session = createSession(mailInfo);
        try {
            MimeMessage msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress(mailInfo.getFromAddress()));
            msg.setRecipient(Message.RecipientType.TO,
                             new InternetAddress(mailInfo.getToAddress()));
            msg.setSubject(mailInfo.getSubject());
            msg.setSentDate(new Date());

            // MimeMultipart 容器
            Multipart mp = new MimeMultipart();
            BodyPart htmlPart = new MimeBodyPart();
            htmlPart.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
            mp.addBodyPart(htmlPart);
            msg.setContent(mp);

            Transport.send(msg);
            return true;
        } catch (MessagingException e) { e.printStackTrace(); return false; }
    }

    /** 統一建立 Session(支援認證) */
    private static Session createSession(MailSenderInfo info) {
        Authenticator auth = null;
        if (info.isValidate()) {
            auth = new MyAuthenticator(info.getUserName(), info.getPassword());
        }
        return Session.getDefaultInstance(info.getProperties(), auth);
    }
}

3. 認證器:MyAuthenticator

package com.util.mail;
import javax.mail.*;

public class MyAuthenticator extends Authenticator {
    private String userName, password;
    public MyAuthenticator() {}
    public MyAuthenticator(String user, String pass) {
        this.userName = user; this.password = pass;
    }
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(userName, password);
    }
}

使用範例:Main 方法一鍵發送

public static void main(String[] args) {
    MailSenderInfo info = new MailSenderInfo();
    info.setMailServerHost("smtp.163.com");
    info.setMailServerPort("25");
    info.setValidate(true);
    info.setUserName("yourname@163.com");
    info.setPassword("yourpassword");  // 授權碼而非登入密碼
    info.setFromAddress("yourname@163.com");
    info.setToAddress("target@example.com");
    info.setSubject("測試主題 - " + System.currentTimeMillis());
    info.setContent("

HTML 內容測試

當前時間:" + new Date() + "

"); SimpleMailSender sender = new SimpleMailSender(); sender.sendHtmlMail(info); // 或 sendTextMail(info) System.out.println("發送完成"); }

五大避坑指南(血淚總結)

  1. 三個類缺一不可,且必須置於同一包(預設 com.util.mail),否則編譯/執行報錯。
  2. 新註冊郵箱無法發信:163/QQ 等郵箱需「養號」一段時間,或開啟「客戶端授權碼」功能,使用授權碼而非登入密碼。
  3. SMTP 主機與發件人域名必須一致:用 smtp.163.com 發信,fromAddress 必須是 @163.com,跨域會被拒收。
  4. 端口與加密:25 端口常被封鎖,建議改用 465 (SSL) 或 587 (STARTTLS),需額外設定 mail.smtp.ssl.enable=true 或 mail.smtp.starttls.enable=true。
  5. 附件支援擴展:當前類未實現附件,需在 sendHtmlMail 中遍歷 attachFileNames,建立 MimeBodyPart 並 attachFile 加入 Multipart。

進階擴展建議

  • 連接池化 Session:高併發場景下避免頻繁創建 Session,使用 Session.getInstance(props, auth) 並緩存。
  • 異步發送:結合 CompletableFuture 或線程池,避免阻塞業務線程。
  • 模板引擎整合:引入 Thymeleaf/FreeMarker 渲染 HTML 模板,分離內容與代碼。
  • 發送狀態追蹤:記錄 Message-ID、發送時間、退信狀態,建立郵件發送審計日誌。

這套封裝已在多個生產項目穩定運行 5 年+,核心原理不變,只有細節配置隨郵箱服務商策略微調。掌握「配置分離、認證封裝、內容多態」三原則,JavaMail 即變得簡單可控。

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