news 2026/10/17 13:08:32

SpringBoot 复杂邮件发送实战:附件 / HTML 模板 / 多收件人(含错误排查 + 最佳实践)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot 复杂邮件发送实战:附件 / HTML 模板 / 多收件人(含错误排查 + 最佳实践)

一、知识点背景

在 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.yml中password填的是 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. 日志记录:记录邮件发送状态(成功 / 失败),便于排查问题。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 21:28:48

Flutter Web 与桌面端开发实战:一套代码跑全平台!

一、前言 很多人以为 Flutter 只能做移动端&#xff0c;其实从 Flutter 2.0 起已正式支持 Web 和桌面端&#xff01;本文将带你构建一个“跨五端”应用&#xff08;Android、iOS、Web、Windows、macOS&#xff09;&#xff0c;并解决平台适配的关键问题。 二、启用多平台支持 …

作者头像 李华
网站建设 2026/10/15 3:30:35

解决‘此扩展程序不再受支持’问题:兼容FLUX.1-dev开发工具链

解决“此扩展程序不再受支持”问题&#xff1a;兼容FLUX.1-dev开发工具链 在AI生成内容&#xff08;AIGC&#xff09;工具快速迭代的今天&#xff0c;许多开发者都曾遇到过这样一个令人头疼的问题&#xff1a;昨天还能正常运行的插件&#xff0c;今天一打开却弹出一条刺眼的提示…

作者头像 李华
网站建设 2026/10/17 1:41:43

利用HunyuanVideo-Foley和GitHub开源生态构建自动化视频后期流水线

利用HunyuanVideo-Foley和GitHub开源生态构建自动化视频后期流水线 在短视频日均产量突破千万条的今天&#xff0c;内容创作者正面临一个尴尬的现实&#xff1a;精心拍摄的画面配上“干瘪”的无声回放&#xff0c;观众三秒内就会划走。而专业音效制作动辄数小时、依赖音频工程师…

作者头像 李华
网站建设 2026/10/16 10:26:27

9 个继续教育课堂汇报工具,降AI率AIGC推荐

9 个继续教育课堂汇报工具&#xff0c;降AI率AIGC推荐 在论文与汇报的重压下&#xff0c;谁来帮我们解困&#xff1f; 对于继续教育领域的学习者和从业者来说&#xff0c;课堂汇报、论文写作、文献综述等任务早已成为日常工作的“必修课”。然而&#xff0c;面对繁重的任务量、…

作者头像 李华
网站建设 2026/10/17 9:02:00

9 个专科生降重工具,AI 文献综述免费网站推荐

9 个专科生降重工具&#xff0c;AI 文献综述免费网站推荐 论文写作的“三座大山”&#xff1a;时间、重复率与无尽的修改 对于专科生来说&#xff0c;写论文并不是一件轻松的事。尤其是当面对文献综述这一环节时&#xff0c;很多人会感到无从下手。文献综述需要大量阅读资料、整…

作者头像 李华
网站建设 2026/10/16 8:44:39

10个降AI率工具推荐,继续教育论文必备

10个降AI率工具推荐&#xff0c;继续教育论文必备 AI检测飘红&#xff0c;论文改写陷入困境 在继续教育的学术道路上&#xff0c;论文写作早已成为每位学员必须面对的一道难关。尤其是在当前人工智能技术迅速发展的背景下&#xff0c;越来越多的高校和科研机构开始引入AI检测系…

作者头像 李华