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

JavaMail 發送郵件完整指南:認證、SSL/TLS、HTML、附件與異步優化

     編輯:Java 相關知識

核心依賴

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>

認證器實現

public class SmtpAuthenticator extends Authenticator {
    private final String username, password;
    public SmtpAuthenticator(String username, String password) {
        this.username = username; this.password = password;
    }
    @Override protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username, password);
    }
}

郵件發送核心類

public class MailSender {
    private final Session session;
    private final String from;

    public MailSender(String host, int port, String user, String pass, boolean ssl, String from) {
        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);
        props.put("mail.smtp.auth", "true");
        if (ssl) {
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.socketFactory.port", port);
        } else {
            props.put("mail.smtp.starttls.enable", "true");
        }
        this.session = Session.getInstance(props, new SmtpAuthenticator(user, pass));
        this.from = from;
    }

    /** 發送純文本 */
    public void sendText(String to, String subject, String text) throws MessagingException {
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress(from));
        msg.setRecipients(Message.RecipientType.TO, to);
        msg.setSubject(subject, "UTF-8");
        msg.setText(text, "UTF-8");
        Transport.send(msg);
    }

    /** 發送 HTML */
    public void sendHtml(String to, String subject, String html) throws MessagingException {
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress(from));
        msg.setRecipients(Message.RecipientType.TO, to);
        msg.setSubject(subject, "UTF-8");
        MimeBodyPart htmlPart = new MimeBodyPart();
        htmlPart.setContent(html, "text/html;charset=UTF-8");
        MimeMultipart mp = new MimeMultipart();
        mp.addBodyPart(htmlPart);
        msg.setContent(mp);
        Transport.send(msg);
    }

    /** 發送帶附件 */
    public void sendWithAttachment(String to, String subject, String text,
                                   File file, String fileName) throws MessagingException, UnsupportedEncodingException {
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress(from));
        msg.setRecipients(Message.RecipientType.TO, to);
        msg.setSubject(subject, "UTF-8");

        MimeBodyPart textPart = new MimeBodyPart();
        textPart.setText(text, "UTF-8");

        MimeBodyPart attachPart = new MimeBodyPart();
        attachPart.attachFile(file);
        attachPart.setFileName(MimeUtility.encodeText(fileName, "UTF-8", "B"));

        MimeMultipart mp = new MimeMultipart("mixed");
        mp.addBodyPart(textPart);
        mp.addBodyPart(attachPart);
        msg.setContent(mp);
        Transport.send(msg);
    }

    /** 發送帶內嵌圖片 HTML */
    public void sendWithInlineImage(String to, String subject, String html,
                                    File imgFile, String contentId) throws MessagingException {
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress(from));
        msg.setRecipients(Message.RecipientType.TO, to);
        msg.setSubject(subject, "UTF-8");

        MimeBodyPart htmlPart = new MimeBodyPart();
        htmlPart.setContent(html, "text/html;charset=UTF-8");

        MimeBodyPart imgPart = new MimeBodyPart();
        imgPart.attachFile(imgFile);
        imgPart.setContentID("<" + contentId + ">"); // HTML 中引用 cid:contentId
        imgPart.setDisposition(MimeBodyPart.INLINE);

        MimeMultipart related = new MimeMultipart("related");
        related.addBodyPart(htmlPart);
        related.addBodyPart(imgPart);

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

常見郵箱 SMTP 配置

郵箱SMTP 主機SSL 端口STARTTLS 端口備註
QQ 郵箱smtp.qq.com465587需開啟 SMTP 服務獲取授權碼
163 郵箱smtp.163.com465/99425/587授權碼非登錄密碼
Gmailsmtp.gmail.com465587需開啟「低安全性應用」或應用專用密碼
Outlooksmtp.office365.com—587強制 STARTTLS

異步發送與重試機制

@Service
public class AsyncMailService {
    @Autowired private MailSender mailSender;
    @Autowired private TaskExecutor mailExecutor; // 專用線程池

    public void sendAsync(String to, String subject, String html) {
        mailExecutor.execute(() -> {
            int retry = 3;
            while (retry-- > 0) {
                try {
                    mailSender.sendHtml(to, subject, html);
                    return;
                } catch (MessagingException e) {
                    if (retry == 0) log.error("郵件發送最終失敗: {}", to, e);
                    else { sleep(2000); }
                }
            }
        });
    }
}

Spring Boot 整合

spring:
  mail:
    host: smtp.163.com
    port: 465
    username: xxx@163.com
    password: auth_code
    protocol: smtps
    properties:
      mail:
        smtp:
          ssl:
            enable: true
          auth: true
          timeout: 10000
          connectiontimeout: 10000
          writetimeout: 10000

直接注入 JavaMailSender 使用,無需手寫 MailSender。

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