在企業級應用開發中,郵件發送功能是不可或缺的基礎模組。無論是用戶註冊驗證、密碼重置通知,還是系統告警與報表發送,都需要穩定可靠的郵件服務。本文將完整解析如何使用 JavaMail API 實作基於 SMTP 協議的郵件發送功能,包含核心類別設計、認證機制、異常處理與實戰測試。
為了讓郵件發送邏輯具備良好的擴展性與維護性,我們採用分層封裝策略,將配置屬性、郵件內容、認證邏輯與發送核心分離為四個獨立類別:
集中管理 SMTP 伺服器資訊、發送者/接收者地址、認證憑證、郵件主旨與內容等核心參數,並提供 getProperties() 方法自動生成 JavaMail 所需的 Properties 物件。
public class MailSendProper {
private String host; // SMTP 伺服器位址
private String port; // SMTP 連接埠
private String sendAddress; // 發送者郵箱
private String receiveAddress; // 接收者郵箱
private String username; // 登入帳號
private String password; // 登入密碼
private boolean isValidate = true; // 是否需要身份驗證
private String subject; // 郵件主旨
private String content; // 郵件內容
// Getter/Setter 方法省略...
public Properties getProperties() {
Properties props = new Properties();
props.put("mail.smtp.host", this.host);
props.put("mail.smtp.port", this.port);
props.put("mail.smtp.auth", isValidate ? "true" : "false");
return props;
}
}
輕量級資料傳輸物件,封裝郵件標題、內容與收件人資訊,供業務層調用時傳遞參數使用。
public class EmailMessage {
private String title;
private String context;
private String toEmail;
// 建構子與 Getter/Setter 方法省略...
}
繼承 javax.mail.Authenticator,覆寫 getPasswordAuthentication() 方法,提供帳號密碼驗證邏輯,支援 SMTP 認證機制。
public class MailAttorney extends Authenticator {
private final String username;
private final String password;
public MailAttorney(String username, String password) {
this.username = username;
this.password = password;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
}
整合上述組件,實作郵件會話建立、訊息組裝與發送邏輯。提供兩個靜態方法:mailTest() 接受完整配置物件,sendEmail() 封裝常用預設值(以 126 郵箱為例),方便快速整合。
public class MailSend {
public static boolean mailTest(MailSendProper config) {
Authenticator auth = config.isIsvalidate()
? new MailAttorney(config.getUsername(), config.getPassword())
: null;
Session session = Session.getInstance(config.getProperties(), auth);
Message message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress(config.getSendAddress()));
message.setRecipient(Message.RecipientType.TO,
new InternetAddress(config.getReceiveAddress()));
message.setSubject(config.getSubject());
message.setSentDate(new Date());
message.setText(config.getContent());
Transport.send(message);
return true;
} catch (MessagingException e) {
e.printStackTrace();
return false;
}
}
public static boolean sendEmail(EmailMessage msg) {
MailSendProper config = new MailSendProper();
config.setHost("smtp.126.com");
config.setPort("25");
config.setIsvalidate(true);
config.setUsername("your_email@126.com"); // 請填入實際帳號
config.setPassword("your_auth_code"); // 請填入授權碼而非登入密碼
config.setSendAddress("your_email@126.com");
config.setReceiveAddress(msg.getToEmail());
config.setSubject(msg.getTitle());
config.setContent(msg.getContext());
return mailTest(config);
}
}
smtp.qq.com,埠號 465 (SSL) 或 587 (TLS)smtp.126.com / smtp.163.com,埠號 25/465/587/994smtp.gmail.com,埠號 587 (TLS) 或 465 (SSL)mail.smtp.ssl.enable=true 並使用 SSLSocketFactory。AuthenticationFailedException、SendFailedException、MessagingException 分類處理,並記錄詳細日誌供排查。public static void main(String[] args) {
EmailMessage msg = new EmailMessage();
String verifyCode = String.format("%06d", (int)(Math.random() * 1_000_000));
msg.setTitle("【系統驗證】您的驗證碼");
msg.setContext(String.format("尊敬的用戶您好,您的驗證碼為:%s,請於 5 分鐘內完成驗證。", verifyCode));
msg.setToEmail("target@example.com");
boolean result = MailSend.sendEmail(msg);
System.out.println(result ? "✅ 郵件發送成功" : "❌ 郵件發送失敗,請檢查配置與日誌");
}
@Async 或訊息佇列(RabbitMQ/Kafka)實現非阻塞發送,提升系統響應速度。MimeMessageHelper 設定 setText(htmlContent, true) 發送富文本郵件。MimeMultipart 與 MimeBodyPart 添加附件。掌握 JavaMail 核心 API 後,您可以根據業務需求靈活擴展,構建企業級的郵件通知系統。建議在正式環境部署前,充分測試各郵箱服務商的相容性與發送頻率限制。