Java邮件发送器无法发送邮件,请求排查配置及代码问题
看起来你已经在尝试用Gmail SMTP配置Java邮件发送器了,不过遇到了发送失败的问题对吧?我来帮你一步步排查可能的问题点:
一、先检查YAML配置的问题
YAML对缩进非常敏感,你的配置里存在层级错误,这会导致部分配置无法生效,先修正配置结构:
正确的application.yml邮件配置应该是这样的(注意spring前缀和缩进层级):
spring: mail: host: smtp.gmail.com port: 587 username: MY_EMAIL password: MY_PASSWORD properties: mail: smtp: trust: "*" auth: true starttls: enabled: true required: true connectiontimeout: 5000 timeout: 3000 writetimeout: 5000
你原来的配置里,auth: true和starttls节点没有放在smtp下面,这会导致SMTP认证和STARTTLS的配置不生效,这是常见的缩进坑。
另外还要确认:
- 你用的
password是Google应用密码,而不是普通账号密码,且账号已经开启了两步验证(只有开启两步验证才能生成应用密码),应用密码是16位无空格的字符串,别输错了。 - 检查Gmail账号有没有被限制:如果近期发送过大量邮件被判定为垃圾邮件,Google可能会临时限制你的SMTP发送权限,可以去Gmail的“最近活动”里查看有没有相关提示。
二、代码部分的排查点
@Value的配置键匹配问题
你的代码里用了@Value("${spring.mail.username}"),但如果原来的配置没有spring前缀,这个值会读取失败。所以一定要确保配置里的前缀是spring.mail,和@Value里的键对应上。异步方法的异常处理
你的sendEmail方法加了@Async,但直接抛出MessagingException,异步方法的异常默认不会被主线程捕获,你根本看不到具体的错误原因!建议在方法内部捕获异常并打印日志:
@Async public void sendEmail(String to, String userName, EmailTemplateName emailTemplate, String confirmationUrl, String activationCode, String subject) { try { String templateName; if(emailTemplate == null){ // 你的模板判断逻辑,示例默认模板 templateName = "default-email-template"; } else { templateName = emailTemplate.getTemplateName(); } // 构建邮件内容 MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); helper.setFrom(mailOrigin); helper.setTo(to); helper.setSubject(subject); // 渲染模板 Context context = new Context(); context.setVariable("userName", userName); context.setVariable("confirmationUrl", confirmationUrl); context.setVariable("activationCode", activationCode); String htmlContent = templateEngine.process(templateName, context); helper.setText(htmlContent, true); mailSender.send(message); } catch (MessagingException e) { // 打印详细日志,这是排查问题的关键 log.error("给收件人{}发送邮件失败", to, e); } }
模板引擎的正确性
确保你的模板文件(比如.html模板)放在src/main/resources/templates目录下,且emailTemplate对应的模板名称和文件名一致,SpringTemplateEngine才能正确渲染模板,如果模板找不到,也会导致发送失败。依赖是否正确引入
确认你的pom.xml(或build.gradle)里已经引入了Spring Boot邮件 starter:
<!-- Maven示例 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
这个依赖会自动配置JavaMailSender,不需要你手动创建Bean,手动创建反而可能覆盖默认配置导致问题。
三、调试技巧:开启邮件日志
最有效的排查方式是开启邮件相关的DEBUG日志,这样能看到SMTP连接、认证、发送的全过程,找到具体错误。在application.yml里添加:
logging: level: org.springframework.mail: DEBUG com.sun.mail: DEBUG
运行项目后,查看日志里的SMTP交互信息,比如是否连接成功、认证是否通过、发送时有没有报错,这些日志会直接告诉你问题出在哪。
备注:内容来源于stack exchange,提问作者Luís Casqueiro

