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

JavaMail 發送郵件完整實作:純文字、HTML 與附件三合一

     編輯:Java 相關知識

前言

JavaMail (javax.mail) 是 Java 平台發送電子郵件的標準 API。本文提供可直接落地的完整工具類,支援純文字、HTML 內容與多附件發送。

核心類別架構

  • Session:郵件會話,保有伺服器設定與認證資訊
  • Message (MimeMessage):郵件主體,含主旨、寄件者、收件者、內容
  • Transport:傳輸協定實作(SMTP),負責實際發送
  • Authenticator:SMTP 認證(帳號/密碼)
  • MimeMultipart + MimeBodyPart:多部分內容(HTML + 附件)容器

完整工具類實作

package com.lgf.email;

import javax.activation.*;
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

public class EmailSender {

    // ===== 設定區 =====
    private static final String SMTP_HOST = "smtp.gmail.com";
    private static final String USERNAME = "your_email@gmail.com";
    private static final String PASSWORD = "your_app_password"; // 應用程式密碼
    private static final String FROM = USERNAME;
    private static final String FROM_NAME = "系統通知";

    // ===== 核心發送邏輯 =====
    private Session createSession() {
        Properties props = new Properties();
        props.put("mail.smtp.host", SMTP_HOST);
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true"); // TLS 加密

        return Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(USERNAME, PASSWORD);
            }
        });
    }

    /** 發送純文字郵件 */
    public void sendText(String to, String subject, String content) throws MessagingException {
        MimeMessage msg = createBaseMessage(to, subject);
        msg.setText(content, "utf-8");
        Transport.send(msg);
    }

    /** 發送 HTML 郵件 */
    public void sendHtml(String to, String subject, String htmlContent) throws MessagingException {
        MimeMessage msg = createBaseMessage(to, subject);
        msg.setContent(htmlContent, "text/html;charset=utf-8");
        Transport.send(msg);
    }

    /** 發送帶附件郵件 */
    public void sendWithAttachments(String to, String subject, String htmlContent, List<File> attachments) throws MessagingException {
        MimeMessage msg = createBaseMessage(to, subject);

        // 建立 Multipart 容器
        Multipart multipart = new MimeMultipart();

        // 1. HTML 內容部分
        MimeBodyPart htmlPart = new MimeBodyPart();
        htmlPart.setContent(htmlContent, "text/html;charset=utf-8");
        multipart.addBodyPart(htmlPart);

        // 2. 附件部分
        for (File file : attachments) {
            MimeBodyPart attachPart = new MimeBodyPart();
            DataSource source = new FileDataSource(file);
            attachPart.setDataHandler(new DataHandler(source));
            // 解決中文檔名編碼問題
            attachPart.setFileName(MimeUtility.encodeText(file.getName()));
            multipart.addBodyPart(attachPart);
        }

        msg.setContent(multipart);
        Transport.send(msg);
    }

    private MimeMessage createBaseMessage(String to, String subject) throws MessagingException {
        Session session = createSession();
        session.setDebug(true); // 開發期開啟除錯

        MimeMessage msg = new MimeMessage(session);
        msg.setSubject(subject, "utf-8");
        msg.setFrom(new InternetAddress(FROM, FROM_NAME, "utf-8"));
        msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
        msg.setSentDate(new Date());
        return msg;
    }

    // ===== 測試主程式 =====
    public static void main(String[] args) {
        EmailSender sender = new EmailSender();
        try {
            // sender.sendText("target@example.com", "測試純文字", "Hello JavaMail!");
            // sender.sendHtml("target@example.com", "測試 HTML", "<h1 style='color:red'>HTML 郵件</h1>");
            sender.sendWithAttachments(
                "target@example.com",
                "測試附件",
                "<p>請查收附件</p>",
                Arrays.asList(new File("report.pdf"), new File("data.xlsx"))
            );
            System.out.println("發送成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

關鍵細節避坑指南

問題解決方案
Gmail/Outlook 拒絕登入開啟「兩步驟驗證」並產生「應用程式密碼」,不可用主密碼
中文附件檔名亂碼MimeUtility.encodeText(fileName) 編碼檔名
HTML 圖片不顯示使用 CID 內嵌圖片:<img src="cid:imageId"> + htmlPart.addRelatedPart(imagePart)
大量發送效能復用 Session、使用連線池、非同步發送佇列
編碼問題統一指定 utf-8:setSubject(sub, "utf-8")、setText(text, "utf-8")

進階:Spring Boot 整合

@ConfigurationProperties(prefix = "mail")
@Data
public class MailProperties {
    private String host;
    private int port;
    private String username;
    private String password;
    private String from;
}

@Service
@RequiredArgsConstructor
public class MailService {
    private final MailProperties props;
    private final JavaMailSender mailSender; // Spring Boot 自動配置

    public void sendHtml(String to, String subject, String html) {
        MimeMessage msg = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(msg, true, "utf-8");
        helper.setFrom(props.getFrom());
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(html, true); // true = HTML
        mailSender.send(msg);
    }
}

結語

JavaMail 功能強大但 API 底層,實務建議封裝為領域服務(EmailService),搭配 Spring Boot JavaMailSender 簡化配置。重點掌握 MimeMultipart 組合 HTML 與附件、中文編碼處理、SMTP 認證與 TLS 設定,即可覆蓋 95% 發送郵件場景。

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