SpringBoot实现邮件发送功能的详细步骤(普通邮件、HTML邮件、附件邮件)

 更新时间:2026年07月15日 08:36:33   作者:张老师技术栈  
还在为SpringBoot邮件发送发愁,本文手把手教你配置JavaMail,轻松搞定文本、HTML、附件和内联图片邮件,掌握Thymeleaf模板和异步批量发送技巧,避开535、554等常见错误,让你的系统通知、验证码推送更高效,需要的朋友可以参考下

邮件发送是后端系统的常见功能——注册验证码、系统告警、周报推送。SpringBoot 封装了 JavaMail,配置简单,API 友好。

一、配置

1. 引入依赖

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

2. 邮箱配置

spring:
  mail:
    host: smtp.qq.com
    port: 465
    username: your_email@qq.com
    password: 你的授权码  # 不是QQ密码,是SMTP授权码
    properties:
      mail:
        smtp:
          auth: true
          ssl:
            enable: true
          socketFactory:
            port: 465
            class: javax.net.ssl.SSLSocketFactory

授权码获取:QQ邮箱 → 设置 → 账号 → 开启SMTP服务 → 生成授权码

二、发送邮件

1. 简单文本邮件

@Service
public class MailService {

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String from;

    public void sendSimpleMail(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);
        mailSender.send(message);
    }
}

2. HTML 邮件

public void sendHtmlMail(String to, String subject, String htmlContent)
        throws MessagingException {
    MimeMessage message = mailSender.createMimeMessage();
    MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
    helper.setFrom(from);
    helper.setTo(to);
    helper.setSubject(subject);
    helper.setText(htmlContent, true);  // true = HTML 格式
    mailSender.send(message);
}

HTML 内容示例:

String html = "<div style='padding:20px;max-width:600px;margin:0 auto'>"
    + "<h2 style='color:#e74c3c'>秒杀成功通知</h2>"
    + "<p>亲爱的用户:</p>"
    + "<p>您在秒杀活动中抢购的商品已成功下单!</p>"
    + "<table border='1' cellpadding='8' style='border-collapse:collapse'>"
    + "<tr><td>订单号</td><td>" + orderNo + "</td></tr>"
    + "<tr><td>商品名称</td><td>iPhone 15</td></tr>"
    + "<tr><td>金额</td><td>¥4999</td></tr>"
    + "</table>
<p>祝您购物愉快!</p></div>";

3. 带附件邮件

public void sendAttachmentMail(String to, String subject,
                                String content, String filePath)
        throws MessagingException {
    MimeMessage message = mailSender.createMimeMessage();
    MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
    helper.setFrom(from);
    helper.setTo(to);
    helper.setSubject(subject);
    helper.setText(content);

    // 添加附件
    File file = new File(filePath);
    helper.addAttachment(file.getName(), file);

    mailSender.send(message);
}

4. 带内联图片

public void sendInlineImageMail(String to, String subject,
                                  String content, String imgPath)
        throws MessagingException {
    MimeMessage message = mailSender.createMimeMessage();
    MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
    helper.setFrom(from);
    helper.setTo(to);
    helper.setSubject(subject);
    helper.setText(
        "<html><body><img src='cid:image1'/><p>" + content + "</p></body></html>",
        true
    );

    FileSystemResource img = new FileSystemResource(new File(imgPath));
    helper.addInline("image1", img);

    mailSender.send(message);
}

三、模板邮件

1. 使用 Thymeleaf 模板

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- resources/templates/mail/welcome.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
    <h2 th:text="'欢迎 ' + ${username} + ' 加入!'">欢迎加入</h2>
    <p>请点击以下链接激活账户:</p>
    <a th:href="${activateUrl}" rel="external nofollow" >激活账户</a>
    <p th:text="'链接有效期:' + ${expireHours} + ' 小时'">有效期</p>
</body>
</html>
@Service
public class TemplateMailService {

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private TemplateEngine templateEngine;

    @Value("${spring.mail.username}")
    private String from;

    public void sendTemplateMail(String to, String subject,
                                  Map<String, Object> params)
            throws MessagingException {
        // 渲染模板
        Context context = new Context();
        context.setVariables(params);
        String html = templateEngine.process("mail/welcome.html", context);

        // 发送
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(html, true);
        mailSender.send(message);
    }
}

四、批量发送

public void sendBatch(List<String> toList, String subject,
                       String content) {
    for (String to : toList) {
        try {
            sendSimpleMail(to, subject, content);
            // 每封间隔 3 秒,避免被判定为垃圾邮件
            Thread.sleep(3000);
        } catch (Exception e) {
            log.error("发送失败: {}", to, e);
        }
    }
}

五、异步发送

@Service
public class AsyncMailService {

    @Async("taskExecutor")
    public void sendMailAsync(String to, String subject, String content) {
        mailService.sendSimpleMail(to, subject, content);
        log.info("邮件已异步发送: {}", to);
    }
}

六、常见问题

1. 535 Error:登录失败

# 原因:用了QQ密码而不是授权码
# 解决:去QQ邮箱 → 设置 → 账号 → 生成授权码
spring:
  mail:
    password: 你的授权码  # 不是QQ密码

2. 554 被判定为垃圾邮件

// 原因:邮件内容太短或太模板化
// 解决:
//   - 内容不要太雷同
//   - 加收件人姓名个性化
//   - 控制发送频率(每分钟不超过 10 封)

3. 发送超时

spring:
  mail:
    properties:
      mail:
        smtp:
          connectiontimeout: 5000
          timeout: 5000
          writetimeout: 5000

七、秒杀系统应用

@Service
public class SeckillMailService {

    @Async("taskExecutor")
    public void notifySeckillResult(Long userId, String productName,
                                     boolean success, String orderNo) {
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("productName", productName);
        params.put("success", success);
        params.put("orderNo", orderNo);

        templateMailService.sendTemplateMail(
            "user@example.com",
            "秒杀结果通知",
            params
        );
    }
}

总结

发送方式:
  简单文本 → SimpleMailMessage
  HTML内容 → MimeMessageHelper(true)
  带附件   → helper.addAttachment()
  内联图片 → helper.addInline()

注意事项:
  使用授权码而非密码
  控制发送频率
  异步发送不影响主流程

到此这篇关于SpringBoot实现邮件发送功能的详细步骤(普通邮件、HTML邮件、附件邮件)的文章就介绍到这了,更多相关SpringBoot邮件发送功能内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot集成Redis,并自定义对象序列化操作

    SpringBoot集成Redis,并自定义对象序列化操作

    这篇文章主要介绍了SpringBoot集成Redis,并自定义对象序列化操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • FilenameUtils.getName 函数源码分析

    FilenameUtils.getName 函数源码分析

    这篇文章主要为大家介绍了FilenameUtils.getName 函数源码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • IntelliJ IDEA2020.1版本更新pom文件自动导包的方法

    IntelliJ IDEA2020.1版本更新pom文件自动导包的方法

    这篇文章主要介绍了IntelliJ IDEA2020.1版本更新pom文件自动导包的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • 详解在Java的Struts2框架中配置Action的方法

    详解在Java的Struts2框架中配置Action的方法

    这篇文章主要介绍了详解在Java的Struts2框架中配置Action的方法,讲解了包括struts.xml中的action配置及基于注解方式Action配置的两个方式,需要的朋友可以参考下
    2016-03-03
  • SpringBoot返回json和xml的示例代码

    SpringBoot返回json和xml的示例代码

    本篇文章主要介绍了SpringBoot返回json和xml的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • MyBatis 源码分析 之SqlSession接口和Executor类

    MyBatis 源码分析 之SqlSession接口和Executor类

    mybatis框架在操作数据的时候,离不开SqlSession接口实例类的作用,下面通过本文给大家实例剖析MyBatis 源码分析之SqlSession接口和Executor类,需要的朋友参考下吧
    2017-02-02
  • MyBatis传入多个参数时parameterType的写法

    MyBatis传入多个参数时parameterType的写法

    这篇文章主要介绍了MyBatis传入多个参数时parameterType的写法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • Spring连接Mysql数据库全过程

    Spring连接Mysql数据库全过程

    这篇文章主要介绍了Spring连接Mysql数据库全过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Java程序开发中abstract 和 interface的区别详解

    Java程序开发中abstract 和 interface的区别详解

    abstract class和interface在Java语言中都是用来进行抽象类。但是两者有什么区别呢,接下来小编给大家带来了abstract 和 interface的区别详解,感兴趣的朋友一起学习吧
    2016-06-06
  • java代码获取数据库表里数据的总数操作

    java代码获取数据库表里数据的总数操作

    这篇文章主要介绍了java代码获取数据库表里数据的总数操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08

最新评论