SpringBoot 复杂邮件发送实战:附件 / HTML 模板 / 多收件人(含错误排查 + 最佳实践)
2026/4/29 7:05:09 网站建设 项目流程

一、知识点背景

在 SpringBoot 项目中,邮件发送是常见功能(如注册通知、告警推送),但单文本邮件无法满足复杂场景(如带样式的通知、多附件报表)。本文详解SpringBoot 3.x整合JavaMailSender实现多收件人 + HTML 模板 + 附件的完整流程,并解决实际开发中的常见问题。

二、学习过程 & 步骤(图文并茂)

步骤 1:引入核心依赖(pom.xml)

在 SpringBoot 项目中,需引入邮件和模板引擎(Thymeleaf)依赖:

xml

<!-- SpringBoot邮件核心依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <!-- Thymeleaf:用于HTML邮件模板 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>

步骤 2:配置邮箱参数(application.yml)

以 QQ 邮箱为例(其他邮箱如网易 / 企业邮箱仅需修改服务器地址):

yaml

spring: mail: # QQ邮箱SMTP服务器地址 host: smtp.qq.com # SMTP端口(SSL加密) port: 465 # 发件人邮箱 username: 你的QQ邮箱@qq.com # 注意:不是QQ密码,是邮箱“授权码”(需在QQ邮箱设置中开启) password: 你的QQ邮箱授权码 # 加密方式(SSL) protocol: smtps properties: mail: smtp: auth: true starttls: enable: true required: true

图 1:QQ 邮箱 “POP3/SMTP 服务” 开启界面(此处建议插入截图:QQ 邮箱→设置→账户→开启 POP3/SMTP 服务的界面)

步骤 3:封装通用邮件工具类

实现多收件人、附件、HTML 模板的复用工具类:

java

运行

package com.example.mail.utils; import jakarta.mail.MessagingException; import jakarta.mail.internet.MimeMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Component; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import java.io.File; /** * SpringBoot邮件发送工具类(支持多收件人、HTML模板、附件) */ @Component public class MailSendUtils { private final JavaMailSender mailSender; private final TemplateEngine templateEngine; // 构造注入(Spring推荐方式) public MailSendUtils(JavaMailSender mailSender, TemplateEngine templateEngine) { this.mailSender = mailSender; this.templateEngine = templateEngine; } /** * 发送带HTML模板+多附件的邮件 * @param to 收件人列表(如:{"user1@qq.com", "user2@163.com"}) * @param subject 邮件主题 * @param templateName Thymeleaf模板名(如:emailTemplate) * @param context 模板参数 * @param attachments 附件列表 */ public void sendTemplateMailWithAttach( String[] to, String subject, String templateName, Context context, File[] attachments ) throws MessagingException { // 1. 创建MimeMessage(支持多部分内容) MimeMessage mimeMessage = mailSender.createMimeMessage(); // 2. 初始化Helper(true=支持多部分,UTF-8=避免中文乱码) MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8"); // 3. 设置邮件基础信息 helper.setFrom("你的QQ邮箱@qq.com"); // 发件人 helper.setTo(to); // 多收件人 helper.setSubject(subject); // 主题 // 4. 渲染Thymeleaf模板为HTML内容 String htmlContent = templateEngine.process(templateName, context); helper.setText(htmlContent, true); // true=内容是HTML // 5. 添加多个附件 if (attachments != null && attachments.length > 0) { for (File file : attachments) { helper.addAttachment(file.getName(), file); } } // 6. 发送邮件 mailSender.send(mimeMessage); } }

步骤 4:编写 HTML 邮件模板

resources/templates下创建emailTemplate.html(Thymeleaf 模板):

html

预览

<!DOCTYPE html> <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>【SpringBoot邮件测试】</title> <style> .content { color: #333; font-size: 14px; line-height: 1.8; } .sign { color: #666; margin-top: 20px; } </style> </head> <body> <div class="content"> <p>您好,<span th:text="${username}">用户</span>!</p> <p>这是一封来自SpringBoot的HTML模板邮件,您的验证码是:<span style="color: #ff4d4f; font-weight: bold;" th:text="${code}">123456</span></p> </div> <div class="sign"> <p>—— SpringBoot邮件测试团队</p> </div> </body> </html>

图 2:Thymeleaf 模板文件目录结构(此处建议插入截图:IDEA 中 resources/templates 下的 emailTemplate.html 位置)

步骤 5:测试邮件发送(Controller 层)

编写接口触发邮件发送:

java

运行

package com.example.mail.controller; import com.example.mail.utils.MailSendUtils; import jakarta.mail.MessagingException; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.thymeleaf.context.Context; import java.io.File; @RestController public class MailController { private final MailSendUtils mailSendUtils; public MailController(MailSendUtils mailSendUtils) { this.mailSendUtils = mailSendUtils; } @GetMapping("/sendMail") public String sendMail() throws MessagingException { // 1. 收件人列表 String[] to = {"收件人1@qq.com", "收件人2@163.com"}; // 2. 邮件主题 String subject = "SpringBoot邮件测试(含模板+附件)"; // 3. 模板参数 Context context = new Context(); context.setVariable("username", "测试用户"); context.setVariable("code", "888888"); // 4. 附件(示例:本地的test.txt文件) File[] attachments = {new File("D:/test.txt")}; // 调用工具类发送邮件 mailSendUtils.sendTemplateMailWithAttach(to, subject, "emailTemplate", context, attachments); return "邮件发送成功!"; } }

三、遇到的问题 & 解决过程

问题 1:MailAuthenticationException(认证失败)

  • 现象:启动项目调用接口后,控制台报错:Authentication failed
  • 原因
    1. 邮箱未开启 “POP3/SMTP 服务”;
    2. application.ymlpassword填的是 QQ 密码(而非授权码)。
  • 解决步骤
    1. 登录 QQ 邮箱→设置→账户→开启 “POP3/SMTP 服务”;
    2. 生成 “授权码”(需验证手机),将password替换为授权码。

问题 2:附件发送后乱码

  • 现象:收件人收到邮件后,附件名称显示为乱码(如 “????.txt”)。
  • 原因MimeMessageHelper未指定编码格式。
  • 解决步骤:在初始化MimeMessageHelper时,显式指定编码为UTF-8

    java

    运行

    MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");

问题 3:SocketTimeoutException(连接超时)

  • 现象:调用接口后长时间无响应,最终报错:Connection timed out
  • 原因
    1. 服务器防火墙屏蔽了 SMTP 端口(如 465);
    2. 网络环境限制(如公司内网禁止外部邮件连接)。
  • 解决步骤
    1. 测试端口连通性:用telnet smtp.qq.com 465验证是否能连接;
    2. 若端口不通,联系运维开放端口;或切换为企业内网邮箱。

四、总结 & 最佳实践

核心总结

  1. SpringBoot 邮件发送的核心是JavaMailSender,配合MimeMessageHelper实现复杂邮件;
  2. 多收件人通过helper.setTo(String[] to)实现,附件通过helper.addAttachment()添加;
  3. Thymeleaf 模板需放在resources/templates目录下,通过TemplateEngine渲染为 HTML。

生产环境最佳实践

  1. 异步发送:用@Async注解 + 线程池异步发送,避免阻塞业务线程:

    java

    运行

    // 在工具类方法上添加@Async @Async public void sendTemplateMailWithAttach(...) { ... }
  2. 异常重试:结合Spring Retry实现邮件发送失败重试(避免网络波动导致的单次失败);
  3. 日志记录:记录邮件发送状态(成功 / 失败),便于排查问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询