JavaMail 是 Java 平台發送郵件的標準 API。本文涵蓋 Maven 依賴、簡單文本郵件、HTML 富文本、多附件、內嵌圖片、SSL/TLS 加密連接、QQ/163/Gmail 郵箱授權碼配置、異步發送線程池封裝,助你快速接入郵件通知能力。
com.sun.mail
jakarta.mail
2.0.1
com.sun.mail
javax.mail
1.6.2
| 屬性鍵 | 說明 | 典型值 |
|---|---|---|
mail.smtp.host | SMTP 服務器地址 | smtp.qq.com, smtp.163.com, smtp.gmail.com |
mail.smtp.port | 端口 | 25/465/587/2525 |
mail.smtp.auth | 是否需要認證 | true |
mail.smtp.ssl.enable | SSL 直連 (隱式 SSL) | true (端口 465) |
mail.smtp.starttls.enable | STARTTLS 升級 (顯式 TLS) | true (端口 587) |
mail.smtp.socketFactory.class | SSL Socket 工廠 | javax.net.ssl.SSLSocketFactory |
mail.debug | 調試輸出協議交互 | true/false |
public void sendText(String to, String subject, String content) {
Properties props = buildProps();
Session session = Session.getInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(USERNAME, PASSWORD);
}
});
try {
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(FROM));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
msg.setSubject(subject, "UTF-8");
msg.setText(content, "UTF-8");
Transport.send(msg);
} catch (MessagingException e) { throw new RuntimeException(e); }
}
msg.setContent("歡迎註冊
您的驗證碼: 123456
", "text/html;charset=UTF-8");
public void sendWithAttachments(String to, String subject, String html,
List attachments, Map inlineImages) {
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(FROM));
msg.setRecipients(Message.RecipientType.TO, to);
msg.setSubject(subject, "UTF-8");
// 根容器: mixed (附件) -> related (內嵌圖片+HTML) -> alternative (文本/HTML)
MimeMultipart mixed = new MimeMultipart("mixed");
MimeMultipart related = new MimeMultipart("related");
MimeMultipart alternative = new MimeMultipart("alternative");
// 文本版本 (可選)
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText("純文本備選內容", "UTF-8");
alternative.addBodyPart(textPart);
// HTML 版本
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(html, "text/html;charset=UTF-8");
alternative.addBodyPart(htmlPart);
related.addBodyPart(alternative);
// 內嵌圖片
for (Map.Entry e : inlineImages.entrySet()) {
MimeBodyPart imgPart = new MimeBodyPart();
imgPart.attachFile(e.getValue());
imgPart.setContentID("<" + e.getKey() + ">"); // HTML 中
imgPart.setDisposition(MimeBodyPart.INLINE);
related.addBodyPart(imgPart);
}
MimeBodyPart relatedWrapper = new MimeBodyPart();
relatedWrapper.setContent(related);
mixed.addBodyPart(relatedWrapper);
// 附件
for (File file : attachments) {
MimeBodyPart att = new MimeBodyPart();
att.attachFile(file);
att.setFileName(MimeUtility.encodeText(file.getName(), "UTF-8", "B")); // 編碼中文文件名
mixed.addBodyPart(att);
}
msg.setContent(mixed);
Transport.send(msg);
}
| 郵箱 | SMTP Host | SSL Port | STARTTLS Port | 授權碼獲取 |
|---|---|---|---|---|
| QQ 郵箱 | smtp.qq.com | 465 | 587 | 設置→賬號→開啟 POP3/SMTP/IMAP → 生成授權碼 |
| 163 郵箱 | smtp.163.com | 465/994 | 587/25 | 設置→客戶端授權密碼 → 開啟 SMTP → 設置授權碼 |
| Gmail | smtp.gmail.com | 465 | 587 | Google 賬號→安全性→兩步驗證→應用專用密碼 |
| Outlook | smtp.office365.com | 587 (STARTTLS) | 587 | 同登錄密碼或應用密碼 |
public class QQMailSender {
private static final String HOST = "smtp.qq.com";
private static final String USER = "your_qq@qq.com";
private static final String AUTH_CODE = "your_16_digit_auth_code"; // 授權碼,非登錄密碼
private static final String FROM = "your_qq@qq.com";
public static void main(String[] args) {
Properties props = new Properties();
props.put("mail.smtp.host", HOST);
props.put("mail.smtp.port", "465");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.debug", "true");
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(USER, AUTH_CODE);
}
});
try {
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(FROM));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress("target@example.com"));
msg.setSubject("JavaMail 測試", "UTF-8");
msg.setText("這是一封來自 Java 的測試郵件。", "UTF-8");
Transport.send(msg);
System.out.println("發送成功");
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
com.sun.mail.smtp.SMTPTransport 連接池或 Spring JavaMailSenderImpl + spring.mail 配置。@Async + 線程池,避免阻塞業務線程;結合消息隊列實現重試、降級、幂等。