连不上SMTP服务器需先确认三件事:host/port与服务商文档一致;使用应用专用密码并开启SMTP服务;检查防火墙或代理是否拦截587/465端口。

JavaMail API 连不上 SMTP 服务器?先确认这三件事
连不上不是代码写错了,大概率是配置和网络层面卡住了。
-
host和port要跟邮件服务商文档对得上——比如 Gmail 是smtp.gmail.com+587(TLS),不是465或本地localhost - 账号密码不能直接填邮箱密码,Gmail/Outlook 等必须用「应用专用密码」或开启「SMTP 服务」;国内企业邮箱常要绑定 IP 白名单
- 防火墙或公司代理可能拦截
587/465出口流量,用telnet smtp.example.com 587手动测通不通比看异常堆栈更直接
发送带附件的邮件时,MimeBodyPart 和 MimeMultipart 怎么嵌套才不乱
附件发出去是空白、乱码或根本没附上,基本是 multipart 层级搞反了。
- 主文本内容必须用一个
MimeBodyPart,附件每个单独一个MimeBodyPart,全部 add 到同一个MimeMultipart(类型设为"mixed") - 千万别把整个
MimeMultipart再塞进另一个MimeMultipart—— 常见于复制粘贴多层嵌套示例,结果邮件客户端解析失败 - 附件路径要用
FileDataSource,别用URL或裸字节流;中文文件名必须调用setFileName(MimeUtility.encodeText("中文.pdf")),否则 Outlook 里显示成=?UTF-8?B?...?=
javax.mail.AuthenticationFailedException 报错但账号明明是对的
这个异常只说明“认证失败”,不告诉你具体哪一步崩了,排查要分层往下压。
- 检查
Session.getInstance(props, auth)传的auth是不是非 null 的javax.mail.Authenticator子类实例,匿名内部类漏写getPasswordAuthentication()返回值就静默失效 - 确认
props里设置了"mail.smtp.auth"="true",且"mail.smtp.starttls.enable"或"mail.smtp.ssl.enable"按端口匹配开启(587用前者,465用后者) - 某些老版本 JavaMail(如 1.4.x)不支持现代 OAuth2 认证,必须升到
com.sun.mail:javax.mail:1.6.2+,否则即使密码正确也报这个错
附件太大导致发送超时或内存溢出?
JavaMail 默认把整个附件读进内存再编码,百兆文件直接 OOM。
立即学习“Java免费学习笔记(深入)”;
- 用
FileDataSource替代ByteArrayDataSource,让 JavaMail 自己按需读取流,而不是一次性 load - 设置超时:在
props中加"mail.smtp.timeout"和"mail.smtp.connectiontimeout"(单位毫秒),避免卡死在 socket connect 阶段 - 如果附件超过 10MB,建议改用邮件服务商提供的 API(如 SendGrid、Mailgun),JavaMail 不适合做大文件中转站
真正麻烦的从来不是怎么写那几行 send(),而是 SMTP 服务商策略、JVM 网络栈行为、以及附件编码链路里哪一层悄悄吞掉了错误信号。盯着异常栈不如先 telnet 一把,或者抓个包看看 TLS 握手到底停在哪一步。










