原创

Spring Boot 使用 Gmail SMTP 发信:认证、TLS 与超时

整理 JavaMailSender 对接 Gmail SMTP 的配置,区分收信协议与发信认证,给出 TLS 参数、超时和错误定位的检查方法。

发信链路先从 SMTP 开始

本篇使用 Spring Boot 的 JavaMailSender 连接 Gmail SMTP。POP 和 IMAP 属于收信相关协议,开启它们不是完成 SMTP 发信的必要步骤。本次删除了原文先启用 POP/IMAP 的操作说明,也不再依赖某个旧版账户设置页面的截图位置。

账户需要使用其支持的认证方式。应用密码需要启用两步验证,且某些组织账户或账户保护设置可能使该选项不可用。它不是账户登录密码,也不应写入文章或代码仓库。采用 OAuth 的应用应按对应认证流程配置,本文不展开。

Maven 依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

依赖版本由项目的 Spring Boot 依赖管理决定。先记录实际 Boot 和邮件库版本,再排查配置差异。

选择一套一致的 TLS 配置

以下使用 587 端口与 STARTTLS 的配置方式;不要同时照抄原文的 465、SSL 和 STARTTLS 混合配置。

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=${MAIL_USERNAME}
spring.mail.password=${MAIL_APP_PASSWORD}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.ssl.enable=false
spring.mail.properties.mail.smtp.connectiontimeout=6000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
spring.mail.default-encoding=UTF-8

环境变量必须由运行环境注入。网络能访问网页并不证明 SMTP 端口可达;遇到连接超时时,要检查服务运行环境的出站网络与 DNS,而不是先反复更换密码。

发送示例

public void sendTest(JavaMailSender sender, String from, String to) {
    SimpleMailMessage message = new SimpleMailMessage();
    message.setFrom(from);
    message.setTo(to);
    message.setSubject("SMTP integration check");
    message.setText("This is a controlled integration test.");
    sender.send(message);
}

示例依赖 org.springframework.mail.SimpleMailMessage 和 org.springframework.mail.javamail.JavaMailSender。from 应与账户允许的发件身份一致,to 使用自己控制的测试邮箱。本次没有发送邮件。

排查顺序与结果解释

  1. 连接失败:检查主机、端口、DNS 和网络。
  2. TLS 握手失败:检查证书信任、协议配置和运行时环境。
  3. 认证失败:检查账户能力、认证方式与凭据状态,不输出实际凭据。
  4. 发送调用成功但未收到:检查收件地址、垃圾邮件和邮件退信信息。

若用于验证码,邮件投递流程之外还需要独立处理验证码有效期、频率限制和业务幂等。这些不是 JavaMailSender 自动提供的能力。

参考

正文到此结束