根本原因是QQ邮箱默认关闭SMTP服务且需用授权码而非密码;须在网页版设置中开启SMTP并生成16位授权码,配置host=smtp.qq.com、port=587、auth=true,中文及附件需正确编码,注意发送频率限制与日志闭环。

JavaMail连接QQ邮箱报错 AuthenticationFailedException
根本原因不是密码填错了,而是QQ邮箱默认关闭SMTP服务,且必须用授权码而非账户密码。开启路径是QQ邮箱网页版 → 设置 → 账户 → “POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务” → 找到SMTP那一栏点“开启”,然后生成并复制弹出的16位授权码。
常见错误现象:javax.mail.AuthenticationFailedException: 535 Error: authentication failed 或 530 Mail from must equal authorized user,基本都卡在这一步。
- 授权码不是QQ登录密码,也不是手机验证码,是单独生成的一次性长字符串
- 如果用企业QQ或微信邮箱,不支持该授权码机制,得换邮箱或走API
- 开启SMTP后,部分账号需等待1小时才生效(尤其新注册或长期未登录的号)
JavaMail发送代码里必须设对的三个关键参数
QQ邮箱SMTP服务器固定为 smtp.qq.com,端口和加密方式必须匹配,否则会卡在连接阶段或被静默拒绝。
-
mail.smtp.host=smtp.qq.com -
mail.smtp.port=587(推荐),或465(仅限SSL,需额外设mail.smtp.ssl.enable=true) -
mail.smtp.auth=true(必须显式开启认证)
漏掉任意一个,都会导致 javax.mail.MessagingException: Could not connect to SMTP host 或超时无响应。别信网上某些示例写成 smtp.gmail.com 或端口用 25 —— QQ不认。
立即学习“Java免费学习笔记(深入)”;
JavaMail发信时中文乱码、附件打不开、收件人显示异常
本质是MIME头没声明编码或Content-Type不匹配。QQ邮箱对头信息比Gmail更敏感,尤其在批量报警场景下容易触发拦截或解析失败。
- 主题和正文必须用
MimeMessage.setText(..., "UTF-8")或setText(..., "UTF-8", "html")显式指定编码 - 附件名含中文时,要用
MimeUtility.encodeText("报告.pdf", "UTF-8", "B")包一层再塞进setFileName() - 收件人地址不能直接拼字符串,必须用
new InternetAddress("xxx@qq.com", "报警系统", "UTF-8")构造,否则名字部分可能被截断或转义失败
不处理这些,轻则邮件标题变成问号,重则整个邮件被QQ当作垃圾邮件丢弃,连发件箱都找不到记录。
生产环境报警邮件频繁失败或被限频
QQ邮箱对单账号SMTP调用有明确限制:每分钟最多发60封,每天上限500封(具体数值以QQ邮箱后台实时提示为准)。报警类应用很容易踩中这个阈值,尤其是服务抖动时批量触发。
- 别用同一个QQ号发所有服务的告警,按业务线拆分邮箱账号
- 加简单退避逻辑:首次失败后等1s重试,第二次失败等3s,第三次直接跳过并记日志
- 务必检查
Transport.send()是否包裹了try-catch,否则一次失败会导致后续所有告警静默丢失
最常被忽略的是日志闭环——只打印“发送失败”,却不记录原始异常堆栈和邮件内容快照,下次排查时完全无法还原现场。











