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

JSP 整合 JavaMail 實現郵件發送完整指南:Session、Transport、MimeMessage、附件與異常處理

     編輯:Java 相關知識

JavaMail 核心架構四大對象

JavaMail API 以四大核心對象封裝郵件發送全流程:

  • Properties:郵件會話配置 (SMTP 服務器、認證、SSL、超時)。
  • Session:郵件會話上下文,線程安全,可共享,負責創建 Message/Transport/Store。
  • Message (MimeMessage):郵件實體 (發件人、收件人、主題、正文、附件、頭部)。
  • Transport:發送協議實現 (SMTP),負責連接服務器、認證、提交郵件。

基礎發送流程代碼 (JSP 頁面直寫版)

<%@ page import="javax.mail.*, javax.mail.internet.*, javax.activation.*, java.util.*" %>
<%@ page contentType="text/html;charset=UTF-8" %>
<html><body>
<h2>JavaMail 郵件發送測試</h2>
<%
    // 1. 配置屬性
    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.example.com");        // SMTP 服務器
    props.put("mail.smtp.port", "25");                      // 端口 (25/465/587)
    props.put("mail.smtp.auth", "true");                    // 需要認證
    // SSL 配置 (如 465 端口)
    // props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    // props.put("mail.smtp.socketFactory.port", "465");
    // props.put("mail.smtp.socketFactory.fallback", "false");
    // TLS 配置 (如 587 端口 STARTTLS)
    // props.put("mail.smtp.starttls.enable", "true");
    
    // 2. 創建 Session (無需 Authenticator 若僅發送)
    Session session = Session.getInstance(props, null);
    session.setDebug(true); // 控制台輸出 SMTP 交互日誌,調試必備
    
    // 3. 構建 MimeMessage
    Message msg = new MimeMessage(session);
    msg.setFrom(new InternetAddress("sender@example.com", "發件人名稱", "UTF-8"));
    msg.setRecipients(Message.RecipientType.TO, 
        InternetAddress.parse("recipient1@example.com, recipient2@example.com"));
    msg.setSubject("測試郵件主題", "UTF-8");
    msg.setSentDate(new Date());
    
    // 4. 設置純文本正文
    msg.setText("這是純文本郵件正文內容。", "UTF-8");
    // 或設置 HTML 正文: msg.setContent("

HTML 內容

", "text/html;charset=UTF-8"); // 5. 發送 Transport transport = session.getTransport("smtp"); transport.connect("smtp.example.com", "username", "password"); // 顯式連接認證 transport.sendMessage(msg, msg.getAllRecipients()); transport.close(); out.println("<font color='green'>郵件發送成功!</font>"); %> </body></html>

進階功能:HTML 正文、附件、內嵌圖片 (MimeMultipart)

// 構建多部分郵件
MimeMultipart multipart = new MimeMultipart("mixed"); // mixed: 附件; related: 內嵌圖片; alternative: 文本/HTML 替代

// 1. HTML 正文部分
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent("<h1>你好</h1><p>內嵌圖片: <img src='cid:image001'></p>", "text/html;charset=UTF-8");
multipart.addBodyPart(htmlPart);

// 2. 內嵌圖片部分 (related 子集)
MimeBodyPart imagePart = new MimeBodyPart();
DataSource fds = new FileDataSource("/path/to/logo.png");
imagePart.setDataHandler(new DataHandler(fds));
imagePart.setHeader("Content-ID", "<image001>"); // CID 引用
imagePart.setDisposition(MimeBodyPart.INLINE);
multipart.addBodyPart(imagePart);

// 3. 附件部分
MimeBodyPart attachPart = new MimeBodyPart();
DataSource attachSrc = new FileDataSource("/path/to/report.pdf");
attachPart.setDataHandler(new DataHandler(attachSrc));
attachPart.setFileName(MimeUtility.encodeText("報告.pdf", "UTF-8", "B")); // 編碼中文文件名
attachPart.setDisposition(MimeBodyPart.ATTACHMENT);
multipart.addBodyPart(attachPart);

// 4. 設置到 Message
msg.setContent(multipart);

表單驅動發送 JSP (接收前台參數)

<%@ page import="javax.mail.*, javax.mail.internet.*, javax.activation.*, java.util.*" %>
<%
    String to = request.getParameter("to");
    String subject = request.getParameter("subject");
    String text = request.getParameter("text");
    String from = request.getParameter("from"); // 或固定配置
    
    // 基本校驗
    if (to == null || to.trim().isEmpty()) {
        out.println("收件人不能為空");
        return;
    }
    
    try {
        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.example.com");
        props.put("mail.smtp.auth", "true");
        // ... 其他配置
        
        Session session = Session.getInstance(props, null);
        Message msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress(from));
        msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
        msg.setSubject(subject, "UTF-8");
        msg.setText(text, "UTF-8");
        msg.setSentDate(new Date());
        
        Transport transport = session.getTransport("smtp");
        transport.connect("username", "password");
        transport.sendMessage(msg, msg.getAllRecipients());
        transport.close();
        
        out.println("郵件已發送至: " + to);
    } catch (MessagingException e) {
        out.println("發送失敗: " + e.getMessage());
        e.printStackTrace(); // 日誌記錄
    } catch (Exception e) {
        out.println("系統錯誤: " + e.getMessage());
    }
%>

關鍵配置參數速查表 (props.put(key, value))

參數名說明典型值
mail.smtp.hostSMTP 服務器地址smtp.qq.com, smtp.gmail.com, smtp.exmail.qq.com
mail.smtp.portSMTP 端口25 (明文), 465 (SSL), 587 (STARTTLS)
mail.smtp.auth是否認證true
mail.smtp.socketFactory.classSSL Socket 工廠javax.net.ssl.SSLSocketFactory (465 端口必填)
mail.smtp.socketFactory.portSSL 端口465
mail.smtp.starttls.enable啟用 STARTTLStrue (587 端口)
mail.smtp.timeoutSocket 讀取超時 (ms)10000
mail.smtp.connectiontimeout連接超時 (ms)10000
mail.debug調試輸出true/false

常見發送失敗原因與解決

  1. 535 Authentication failed:用戶名/密碼錯誤。QQ/163/Gmail 等需使用**授權碼**而非登錄密碼。
  2. Connection timed out / Could not connect:網絡不通、端口被封 (雲服務器常禁 25 端口)、防火牆。解決:改用 465 SSL 或 587 STARTTLS;檢查安全組/防火牆。
  3. 550 Mail content denied / Spam rejected:內容觸發反垃圾規則。避免大量鏈接、敏感詞;配置 SPF/DKIM/DMARC 域名解析。
  4. 中文亂碼:統一使用 UTF-8:InternetAddress(addr, name, "UTF-8"), setSubject(subj, "UTF-8"), setText(text, "UTF-8"), MimeUtility.encodeText(filename, "UTF-8", "B")。
  5. javax.activation 不存在:JDK 9+ 移除了 JavaBeans Activation Framework。**解決**:添加 Maven 依賴 com.sun.activation:javax.activation:1.2.0。

生產環境最佳實踐

  • 異步發送:將郵件任務放入隊列 (JMS/RabbitMQ/Redis List),後台線程池消費發送,避免阻塞 HTTP 請求。
  • 連接池:JavaMail Session 線程安全可復用,但 Transport 連接不可共享。可自行實現 Transport 池或使用 Spring JavaMailSender (內部管理連接)。
  • 模板引擎:使用 Thymeleaf/FreeMarker 渲染 HTML 郵件模板,分離代碼與內容。
  • 重試機制:發送失敗指數退避重試 (3 次),最終進入死信隊列人工介入。
  • 日誌審計:記錄發送時間、收件人、主題、Message-ID、SMTP 響應碼,便於追蹤。

總結

JavaMail 以 Properties -> Session -> MimeMessage -> Transport 四步封裝了 SMTP 協議細節。掌握 MimeMultipart 構建富文本/附件郵件、SSL/TLS 配置、中文編碼處理、異常排查,是 Java 開發者實現「郵件通知」功能的必備技能。生產環境務必採用**異步發送 + 模板引擎 + 重試審計**架構。

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