JavaMail发送邮件必须正确配置host、port、TLS/SSL及认证参数,使用Authenticator提供凭据,纯文本/HTML/附件邮件构建方式不同,且JDK11+/Spring Boot 3+需迁移到Jakarta Mail。

JavaMail API 发送邮件前必须配置的几个关键参数
不配对 mail.smtp.host、mail.smtp.port 和认证开关,javax.mail.AuthenticationFailedException 几乎必现。Gmail、Outlook、企业邮箱的端口和 TLS/SSL 要求各不相同:
- Gmail:用
smtp.gmail.com,端口587(STARTTLS)或465(SSL),必须开启mail.smtp.auth且关闭mail.smtp.ssl.enable(587 时);若用 465,则设mail.smtp.ssl.enable=true - QQ 邮箱:
smtp.qq.com,端口587,mail.smtp.starttls.enable=true,不能开ssl.enable - 企业 Exchange 或自建 SMTP:需确认是否强制要求
mail.smtp.ssl.trust指定主机名,否则抛javax.net.ssl.SSLHandshakeException
Authenticator 不是可选项,而是连接凭据的唯一载体
Session.getInstance(props, new Authenticator()) 中的 Authenticator 子类必须重写 getPasswordAuthentication(),返回含用户名密码的 PasswordAuthentication 对象。常见错误包括:
- 直接传
null或空字符串给new PasswordAuthentication(...)→ 登录被拒 - 用邮箱完整地址(如
user@gmail.com)作用户名,但某些 SMTP 服务只要求前缀(user) - 密码填的是邮箱登录密码,而 Gmail/Outlook 等要求用「应用专用密码」(App Password),普通密码会失败
发送纯文本和带附件的邮件,MimeMessage 构建逻辑完全不同
别指望一个 MimeMessage 实例能同时满足两类需求。核心区别在 Multipart 的嵌套结构:
- 纯文本:直接
message.setText("hello", "UTF-8")即可,不用Multipart - HTML 邮件:用
message.setContent(htmlStr, "text/html; charset=UTF-8") - 带附件:必须用
MimeMultipart("mixed")作为根容器,再往里加MimeBodyPart(正文)和另一个MimeBodyPart(附件),附件需调用bodyPart.attachFile(file)并设bodyPart.setFileName(...)
漏掉 multipart.addBodyPart(...) 任意一次,附件就发不出去,且无报错提示。
立即学习“Java免费学习笔记(深入)”;
JavaMail 1.6+ 和 Jakarta Mail 2.0+ 的包名与依赖已彻底分离
如果你用的是 JDK 11+ 或 Spring Boot 3+,旧版 javax.mail 已不可用。必须切换到 Jakarta 命名空间:
- Maven 依赖从
com.sun.mail:javax.mail改为com.sun.mail:jakarta.mail - 所有 import 必须更新:例如
javax.mail.Session→jakarta.mail.Session,javax.mail.internet.MimeMessage→jakarta.mail.internet.MimeMessage - 老项目升级时,IDE 可能仍提示 “unresolved symbol”,本质是没清理掉
javax.mail.jar的残留引用,得检查lib/目录和 Maven 的dependency:tree
混淆这两个命名空间会导致运行时报 NoClassDefFoundError 或编译期找不到符号,尤其在混合使用 Spring Framework 5.x(用 javax)和 6.x(用 jakarta)的项目里特别容易踩坑。










