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

JavaMail 發送郵件完整實戰:SMTP 認證、HTML 內容、附件與 Spring Boot 整合

     編輯:Java 相關知識

JavaMail 核心依賴




    com.sun.mail
    jakarta.mail
    2.0.1



    javax.mail
    mail
    1.4.7

核心發送流程


public class EmailSender {
    private final String host;
    private final String username;
    private final String password;
    private final String from;
    private final Properties props;
    
    public EmailSender(String host, int port, String username, String password, String from) {
        this.host = host;
        this.username = username;
        this.password = password;
        this.from = from;
        
        this.props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true"); // TLS 加密
        props.put("mail.smtp.ssl.trust", host);
        props.put("mail.debug", "false");
    }
    
    public void send(EmailMessage msg) throws MessagingException {
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(from));
        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(msg.getTo()));
        message.setSubject(msg.getSubject(), "UTF-8");
        message.setSentDate(new Date());
        
        // 構建內容
        Multipart multipart = new MimeMultipart();
        
        // HTML 正文
        MimeBodyPart htmlPart = new MimeBodyPart();
        htmlPart.setContent(msg.getHtmlContent(), "text/html; charset=UTF-8");
        multipart.addBodyPart(htmlPart);
        
        // 附件(可選)
        if (msg.getAttachments() != null) {
            for (Attachment att : msg.getAttachments()) {
                MimeBodyPart attPart = new MimeBodyPart();
                attPart.attachFile(att.getFile());
                attPart.setFileName(MimeUtility.encodeText(att.getFilename()));
                multipart.addBodyPart(attPart);
            }
        }
        
        message.setContent(multipart);
        
        // 發送
        Transport.send(message);
    }
}

郵件模型類


public class EmailMessage {
    private String to;
    private String subject;
    private String htmlContent;
    private List attachments;
    // getters/setters
}

public class Attachment {
    private File file;
    private String filename;
    // getters/setters
}

常見 SMTP 服務商配置

服務商SMTP 主機端口加密備註
QQ 郵箱smtp.qq.com465/587SSL/TLS需開啟 SMTP 服務,用授權碼非密碼
163 郵箱smtp.163.com465/994SSL/TLS需開啟客戶端授權碼
Gmailsmtp.gmail.com587TLS需開啟「低安全性應用」或應用專用密碼
Outlooksmtp.office365.com587TLS企業郵箱可能不同
企業郵箱自定義25/465/587視配置諮詢 IT 部門

Spring Boot 整合(推薦生產用法)

配置 application.yml


spring:
  mail:
    host: smtp.qq.com
    port: 465
    username: your@qq.com
    password: your_auth_code
    protocol: smtp
    properties:
      mail:
        smtp:
          auth: true
          ssl:
            enable: true
          starttls:
            enable: false
        debug: false

服務層封裝


@Service
public class MailService {
    @Autowired private JavaMailSender mailSender;
    @Value("${spring.mail.username}") private String from;
    
    public void sendHtmlMail(String to, String subject, String html) {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(html, true); // true = HTML
        mailSender.send(message);
    }
    
    public void sendWithAttachment(String to, String subject, String html, File file) 
            throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(html, true);
        helper.addAttachment(MimeUtility.encodeText(file.getName()), file);
        mailSender.send(message);
    }
    
    // 異步發送
    @Async
    public void sendAsync(String to, String subject, String html) {
        sendHtmlMail(to, subject, html);
    }
}

進階主題

批量發送優化

  • 複用 Session 和 Transport 連接
  • 異步線程池發送,避免阻塞主線程
  • 速率限制,避免被判定為垃圾郵件

模板引擎整合


// Thymeleaf 模板
Context context = new Context();
context.setVariable("user", user);
context.setVariable("code", verificationCode);
String html = templateEngine.process("email/verify", context);
mailService.sendHtmlMail(user.getEmail(), "驗證碼", html);

發送狀態追蹤

  • 同步發送:捕獲 MessagingException 判斷成功/失敗
  • 異步發送:持久化發送記錄表,狀態:PENDING/SENT/FAILED
  • 退信處理:配置郵件服務商回調或定期檢查 Bounce 郵箱

常見問題排查

現象可能原因解決
Authentication failed密碼錯誤/未用授權碼檢查郵箱設置,生成授權碼
Could not connect to SMTP host端口/主機錯誤/防火牆telnet 測試連通性,確認端口
550 Mailbox unavailable收件箱不存在/滿/被封驗證郵箱地址有效性
中文附件名亂碼編碼未處理MimeUtility.encodeText(filename)
發送緩慢同步阻塞/DNS 解析慢異步發送、配置本地 DNS 緩存

安全提醒

  • **絕不**在代碼/配置文件中硬編碼密碼,使用環境變量/配置中心
  • 生產環境強制啟用 TLS/SSL
  • 發送頻率控制,避免 IP 被列入黑名單
  • 敏感信息(驗證碼、鏈接)設置過期時間
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved