SpringBoot 集成邮件发送完整实战教程

在日常项目开发中,邮件发送是非常通用的功能,常用于用户注册验证码、密码找回、系统消息推送、业务通知、报表发送等场景。SpringBoot 对 Java 原生邮件 API 进行了极致封装,提供了spring-boot-starter-mail自动化依赖,只需简单配置即可快速实现各类邮件发送功能,极大简化了开发流程。

本文将从零开始,手把手讲解 SpringBoot 集成邮件发送,涵盖普通文本邮件、HTML 富文本邮件、带附件邮件、带静态资源邮件四种常用场景,同时解决配置报错、发送失败等常见问题。

一、开发环境准备

本次实战使用稳定通用的开发环境,适配绝大多数 SpringBoot 项目:

  • SpringBoot 2.7.x / 3.x 版本(通用适配)
  • JDK 1.8+
  • Maven 3.6+
  • 邮箱账号(本文以 QQ 邮箱为例,网易邮箱、企业邮箱配置逻辑一致)

核心前置准备:获取邮箱授权码

第三方客户端登录邮箱不支持原生密码,必须使用授权码,以 QQ 邮箱为例:

  1. 登录 QQ 邮箱网页版 → 设置 → 账户
  2. 开启 POP3/IMAP/SMTP 服务
  3. 发送短信验证,获取 16 位授权码(妥善保存,仅展示一次)

二、引入 Maven 依赖

在 SpringBoot 项目的 pom.xml 文件中,引入邮件核心启动器,无需额外引入其他冗余依赖:

<!-- SpringBoot 邮件核心依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

<!-- 可选:web依赖,用于测试接口 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

三、全局配置文件配置

application.ymlapplication.properties 中配置邮件服务器参数、发送者账号、授权码等核心信息,这是邮件发送的核心配置。

3.1 yml 配置(推荐)

spring:
  # 邮件配置
  mail:
    # SMTP 服务器地址(QQ邮箱:smtp.qq.com,163邮箱:smtp.163.com)
    host: smtp.qq.com
    # SMTP 端口(SSL加密端口:465,普通端口:25)
    port: 465
    # 发送者邮箱账号
    username: 你的QQ邮箱@qq.com
    # 邮箱授权码(重点:不是邮箱登录密码)
    password: 你的16位邮箱授权码
    # 开启SSL加密(必须配置,否则发送报错)
    properties:
      mail:
        smtp:
          ssl:
            enable: true
          # 关闭域名校验,解决部分环境报错问题
          auth: true
          starttls:
            enable: true
            required: true
    # 编码格式统一UTF-8,防止中文乱码
    default-encoding: UTF-8

3.2 properties 配置

# 邮件服务器配置
spring.mail.host=smtp.qq.com
spring.mail.port=465
spring.mail.username=你的QQ邮箱@qq.com
spring.mail.password=你的16位邮箱授权码
spring.mail.default-encoding=UTF-8
# 开启SSL和认证
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.ssl.enable=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

四、核心代码实战(四种邮件场景)

SpringBoot 提供了 JavaMailSender 核心工具类,自动根据配置文件初始化 Bean,我们直接注入使用即可,无需手动创建邮件连接。

4.1 工具类封装

封装邮件工具类,统一实现四种邮件发送方法,方便业务层直接调用,代码解耦、便于维护:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;

/**
 * 邮件发送工具类
 * 支持:文本邮件、HTML邮件、附件邮件、静态资源邮件
 */
@Component
public class EmailUtil {

    // 注入SpringBoot自动配置的邮件发送工具
    @Autowired
    private JavaMailSender javaMailSender;

    // 读取配置文件中的发送者邮箱
    @Value("${spring.mail.username}")
    private String sendFrom;

    /**
     * 1. 发送普通文本邮件
     * @param to 接收者邮箱
     * @param subject 邮件主题
     * @param content 邮件文本内容
     */
    public void sendSimpleEmail(String to, String subject, String content) {
        // 创建简单邮件消息对象
        SimpleMailMessage message = new SimpleMailMessage();
        // 发送者
        message.setFrom(sendFrom);
        // 接收者(多个收件人可传数组)
        message.setTo(to);
        // 邮件主题
        message.setSubject(subject);
        // 邮件文本内容
        message.setText(content);
        // 发送邮件
        javaMailSender.send(message);
    }

    /**
     * 2. 发送HTML富文本邮件(支持标签、样式、图片排版)
     * @param to 接收者邮箱
     * @param subject 邮件主题
     * @param htmlContent HTML格式内容
     * @throws MessagingException 邮件发送异常
     */
    public void sendHtmlEmail(String to, String subject, String htmlContent) throws MessagingException {
        // 创建复杂邮件消息对象
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        // true 表示开启多文件模式(支持富文本、附件)
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);

        helper.setFrom(sendFrom);
        helper.setTo(to);
        helper.setSubject(subject);
        // true 表示内容为HTML格式
        helper.setText(htmlContent, true);

        javaMailSender.send(mimeMessage);
    }

    /**
     * 3. 发送带附件的邮件
     * @param to 接收者邮箱
     * @param subject 邮件主题
     * @param content 邮件文本内容
     * @param filePath 附件本地路径
     * @throws MessagingException 邮件发送异常
     */
    public void sendAttachEmail(String to, String subject, String content, String filePath) throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);

        helper.setFrom(sendFrom);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content);

        // 加载附件文件
        FileSystemResource file = new FileSystemResource(new File(filePath));
        // 获取文件名
        String fileName = file.getFilename();
        // 添加附件(参数:附件名称、文件资源)
        helper.addAttachment(fileName, file);

        javaMailSender.send(mimeMessage);
    }

    /**
     * 4. 发送带静态图片资源的HTML邮件
     * @param to 接收者邮箱
     * @param subject 邮件主题
     * @param htmlContent 带图片占位符的HTML内容
     * @param imgPath 图片本地路径
     * @param imgId 图片唯一ID(与HTML占位符对应)
     * @throws MessagingException 邮件发送异常
     */
    public void sendImgHtmlEmail(String to, String subject, String htmlContent, String imgPath, String imgId) throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);

        helper.setFrom(sendFrom);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(htmlContent, true);

        // 添加静态图片资源,绑定ID
        FileSystemResource img = new FileSystemResource(new File(imgPath));
        helper.addInline(imgId, img);

        javaMailSender.send(mimeMessage);
    }
}

4.2 测试接口编写

编写测试 Controller,启动项目后通过接口快速测试各类邮件发送功能:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.mail.MessagingException;

@RestController
@RequestMapping("/email")
public class EmailController {

    @Autowired
    private EmailUtil emailUtil;

    // 测试发送普通文本邮件
    @GetMapping("/send/simple")
    public String sendSimple() {
        try {
            emailUtil.sendSimpleEmail("接收邮箱@qq.com", "SpringBoot测试文本邮件", "Hello SpringBoot 邮件发送!");
            return "文本邮件发送成功";
        } catch (Exception e) {
            return "文本邮件发送失败:" + e.getMessage();
        }
    }

    // 测试发送HTML邮件
    @GetMapping("/send/html")
    public String sendHtml() {
        try {
            String html = "<h3 style='color:red'>SpringBoot HTML邮件测试</h3><p>这是富文本邮件,支持样式、字体、颜色排版</p>";
            emailUtil.sendHtmlEmail("接收邮箱@qq.com", "SpringBoot测试HTML邮件", html);
            return "HTML邮件发送成功";
        } catch (MessagingException e) {
            return "HTML邮件发送失败:" + e.getMessage();
        }
    }

    // 测试发送带附件邮件
    @GetMapping("/send/attach")
    public String sendAttach() {
        try {
            // 替换为本地真实文件路径
            String filePath = "D:/test.pdf";
            emailUtil.sendAttachEmail("接收邮箱@qq.com", "带附件邮件测试", "您好,本次发送附带附件文件,请查收!", filePath);
            return "附件邮件发送成功";
        } catch (MessagingException e) {
            return "附件邮件发送失败:" + e.getMessage();
        }
    }

    // 测试发送带图片的HTML邮件
    @GetMapping("/send/img")
    public String sendImg() {
        try {
            // 图片ID,用于HTML绑定
            String imgId = "testImg";
            String html = "<h3>带图片的邮件测试</h3><p>本地图片展示:</p><img src='cid:" + imgId + "'/>";
            // 替换为本地真实图片路径
            String imgPath = "D:/test.png";
            emailUtil.sendImgHtmlEmail("接收邮箱@qq.com", "图片邮件测试", html, imgPath, imgId);
            return "图片邮件发送成功";
        } catch (MessagingException e) {
            return "图片邮件发送失败:" + e.getMessage();
        }
    }
}

五、项目测试运行

  1. 修改配置文件中的发送邮箱、授权码为自己的真实信息;
  2. 修改测试接口中的接收邮箱、文件路径、图片路径为真实有效数据;
  3. 启动 SpringBoot 项目,无报错即配置成功;
  4. 浏览器访问对应接口,即可完成邮件发送测试。

六、常见报错及解决方案

1. 认证失败 535 error

原因:密码填写错误、未开启 POP3/SMTP 服务、授权码过期

解决:确认填写的是授权码而非登录密码,重新开启邮箱服务并刷新授权码。

2. SSL 连接失败、端口异常

原因:未开启 SSL 加密、端口配置不匹配

解决:465 端口必须开启 SSL,25 端口关闭 SSL,严格对应配置。

3. 邮件中文乱码

原因:编码格式未统一

解决:配置文件指定 default-encoding: UTF-8

4. 附件文件找不到

原因:文件路径错误、文件不存在、权限不足

解决:使用绝对路径测试,确认文件存在,项目拥有文件读取权限。

七、拓展优化建议

  • 异步发送:邮件发送属于 IO 耗时操作,可结合 Spring 的 @Async 实现异步发送,不阻塞主线程;
  • 模板邮件:整合 Thymeleaf / FreeMarker 实现邮件模板,快速制作美观的通知邮件、验证码邮件;
  • 异常重试:添加邮件发送失败重试机制,避免网络波动导致发送失败;
  • 日志记录:记录邮件发送日志(收件人、主题、发送状态),便于问题排查。

总结

SpringBoot 集成邮件发送核心流程极简:引入依赖 → 配置邮箱服务与授权码 → 注入JavaMailSender → 封装工具类实现不同邮件场景。本文覆盖了项目开发中 99% 的邮件使用场景,代码可直接复用,适配所有 SpringBoot 版本,开箱即用、稳定高效。


作 者:南烛
链 接:https://www.itnotes.top/archives/1441
来 源:IT笔记
文章版权归作者所有,转载请注明出处!


上一篇