springboot实现邮件发送并支持附件教程

 更新时间:2026年06月18日 09:48:04   作者:weixin_44550006  
本文详细介绍了在SpringBoot中实现异步邮件发送功能的方法,涵盖自定义主题、发送文件、群发等内容,并强调了使用Transport处理邮件及配置QQ邮箱时需使用授权码的关键步骤

在 Spring Boot 中实现异步邮件发送功能,支持自定义主题、发送文件、自定义内容以及群发,可以通过以下步骤完成。

可以使用Transport来处理邮件发送,并结合 Spring 的异步功能注解@Async来实现异步发送。

1 引入依赖

 <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>javax.mail</artifactId>
            <version>1.6.2</version>
        </dependency>

2 配置邮件发送属性

#企业微信发邮件配置
mail:
  transport:
    protocol: ssl
  smtp:
    host: smtp.exmail.qq.com # 企业微信的host
    port: 465 #邮件服务器的端口号
    auth: true
    ssl:
      enable: true
    from: xxxxx  # 发送邮件
  enable: true
  account: xxxxx # 用于身份验证的邮箱地址
  password: xxxxx #用于身份验证的邮箱地址 密码

需要注意的是如果是qq邮箱,host应该替换为:smtp.qq.com ,port 也不是465而是587,且password不是对应邮箱的密码,而是一个随机生成的授权码。

3 创建邮件服务

package com.gotion.framework.email;
import java.util.List;
/**
 * 邮件发送Service
 * @Description
 * @Author
 **/
public interface ISendEmailService {
    /**
     * 发送邮件
     * @param fromAliasName 别名
     * @param to 发送目标
     * @param subject 主题
     * @param content 内容
     * @param attachFileList 附件
     */
    void send(String fromAliasName,String to,String subject,String content, List<String> attachFileList);
}
package com.gotion.framework.email.impl;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.gotion.framework.email.ISendEmailService;
import com.sun.mail.util.MailSSLSocketFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.util.Date;
import java.util.List;
import java.util.Properties;
/**
 * 邮件发送工具类
 * 注:腾讯企业微信邮箱需要用SSL方式发送
 * @author
 */
@Slf4j
@Service
@ConditionalOnProperty("mail")
public class SendEmailServiceImpl implements ISendEmailService {
    @Value("${mail.account}")
    private  String account ;
    /**
     * 登录密码
     */
    @Value("${mail.password}")
    private  String password;
    /**
     * 发信协议
     */
    @Value("${mail.transport.protocol}")
    private String protocol;
    /**
     * 邮件服务器地址
     */
    @Value("${mail.smtp.host}")
    private String host;
    /**
     * 邮件发送方
     */
    @Value("${mail.smtp.from}")
    private String from;
    /**
     * 发信端口
     */
    @Value("${mail.smtp.port}")
    private String port ;
    /**
     * 发信端口
     */
    @Value("${mail.smtp.auth}")
    private String auth ;
    @Value("${mail.smtp.ssl.enable}")
    private String sslEnable ;
    /**
     * 发送邮件
     */
    @Override
    @Async
    public void send(String fromAliasName, String to, String subject, String content, List<String> attachFileList) {
        // 设置邮件属性
        Properties prop = new Properties();
        prop.setProperty("mail.transport.protocol", protocol);
        prop.setProperty("mail.smtp.host", host);
        prop.setProperty("mail.smtp.port", port);
        prop.setProperty("mail.smtp.auth", auth);
        prop.setProperty("mail.smtp.ssl.protocols", "TLSv1.2");
        prop.setProperty("mail.smtp.from", from);
        MailSSLSocketFactory sslSocketFactory = null;
        try {
            sslSocketFactory = new MailSSLSocketFactory();
            sslSocketFactory.setTrustAllHosts(true);
        } catch (GeneralSecurityException e) {
            log.error("MailSSLSocketFactory set fail",e);
        }
        if (sslSocketFactory == null) {
            log.error("Failed to enable MailSSLSocketFactory");
        } else {
            prop.put("mail.smtp.ssl.enable",sslEnable);
            prop.put("mail.smtp.ssl.socketFactory", sslSocketFactory);
            // 创建邮件会话(注意,如果要在一个进程中切换多个邮箱账号发信,应该用 Session.getInstance)
            Session session = Session.getDefaultInstance(prop, new MyAuthenticator(account, password));
            try {
                MimeMessage mimeMessage = new MimeMessage(session);
                // 设置发件人别名(如果未设置别名就默认为发件人邮箱)
                if (fromAliasName != null && !fromAliasName.trim().isEmpty()) {
                    mimeMessage.setFrom(new InternetAddress(account, fromAliasName));
                }
                // 设置主题和收件人、发信时间等信息
                mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
                mimeMessage.setSubject(subject);
                mimeMessage.setSentDate(new Date());
                // 如果有附件信息,则添加附件
                Multipart multipart = new MimeMultipart();
                MimeBodyPart body = new MimeBodyPart();
                body.setContent(content, "text/html; charset=UTF-8");
                multipart.addBodyPart(body);
                // 添加所有附件(添加时判断文件是否存在)
                if (CollectionUtils.isNotEmpty(attachFileList)){
                    for(String filePath : attachFileList){
                        if(Files.exists(Paths.get(filePath))){
                            MimeBodyPart tempBodyPart = new MimeBodyPart();
                            tempBodyPart.attachFile(filePath);
                            multipart.addBodyPart(tempBodyPart);
                        }
                    }
                }
                mimeMessage.setContent(multipart);
                // 开始发信
                mimeMessage.saveChanges();
                Transport.send(mimeMessage);
            }catch (Exception e) {
                log.error("Fail to send email",e);
            }
        }
    }
    /**
     * 认证信息
     */
    static class MyAuthenticator extends Authenticator {
        /**
         * 用户名
         */
        String username = null;
        /**
         * 密码
         */
        String password = null;
        /**
         * 构造器
         *
         * @param username 用户名
         * @param password 密码
         */
        public MyAuthenticator(String username, String password) {
            this.username = username;
            this.password = password;
        }
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
        }
    }
}

4 启用异步功能

package com.gotion;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableAsync;

/**
 * 启动程序
 *
 */
@EnableAsync
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class GotionApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(GotionApplication.class, args);
    }
}

5 使用邮件服务

import java.util.List;

@RestController
@Slf4j
public class TestEmailSendController {

	@Autowired(required = false)
	private ISendEmailService sendEmailService;

	@PostMapping("/example/send/email")
	public AjaxResult testSendEmail(@RequestParam(required = false) String fromAliasName,
									@RequestParam(required = false) String to,
									@RequestParam(required = false) String subject,
									@RequestParam(required = false) String content,
									@RequestParam(required = false) String attachFiles) {
		List<String> attachFileList = Arrays.stream(attachFiles.split(",")).toList();
		sendEmailService.send(fromAliasName,to,subject,content,attachFileList);
		return AjaxResult.success();
	}
}

6 使用邮件服务


总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • DTD验证xml格式的三种方式详解

    DTD验证xml格式的三种方式详解

    这篇文章主要介绍了DTD验证xml格式的三种方式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Java volatile关键字特性讲解上篇

    Java volatile关键字特性讲解上篇

    JMM要求保证可见性、原子性、有序性,volatile可以保证其中的两个,本篇文章具体验证volatile的可见性,不原子性和禁重排,同时解决volatile的不保证原子性,让代码具有原子性
    2022-12-12
  • java 单例模式和工厂模式实例详解

    java 单例模式和工厂模式实例详解

    这篇文章主要介绍了Java设计模式编程中的单例模式和简单工厂模式以及实例,使用设计模式编写代码有利于团队协作时程序的维护,需要的朋友可以参考下
    2017-04-04
  • 搭建Spring cloud 非阻塞式微服务架构的实现

    搭建Spring cloud 非阻塞式微服务架构的实现

    本文介绍搭建非阻塞式微服务架构,采用Spring Gateway、Spring Security、JWT与Redis,集成EurekaServer、Auth-service、User-service等服务,实现用户认证、日志跟踪及统一入口管理,感兴趣的可以了解一下
    2025-08-08
  • 带你快速搞定java并发库

    带你快速搞定java并发库

    本文主要介绍了java高并发写入用户信息到数据库的几种方法,具有很好的参考价值。下面跟着小编一起来看下吧,希望能给你带来帮助
    2021-07-07
  • java局域网聊天小程序

    java局域网聊天小程序

    这篇文章主要为大家详细介绍了java局域网聊天小程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • Java+mysql本地图片上传数据库及下载示例

    Java+mysql本地图片上传数据库及下载示例

    本篇文章主要介绍了Java+mysql本地图片上传数据库及下载示例,具有一定的参加价值,有兴趣的可以了解一下。
    2017-01-01
  • 解决String字符串转JSONObject顺序不对的问题

    解决String字符串转JSONObject顺序不对的问题

    这篇文章主要介绍了解决String字符串转JSONObject顺序不对的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 基于SpringMVC实现网页登录拦截

    基于SpringMVC实现网页登录拦截

    SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。因此,本文将为大家介绍如何通过SpringMVC实现网页登录拦截功能,需要的小伙伴可以了解一下
    2021-12-12
  • java 中 ChannelHandler的用法详解

    java 中 ChannelHandler的用法详解

    这篇文章主要介绍了java 中 ChannelHandler的用法详解的相关资料,ChannelHandler处理一个I/O event或者拦截一个I/O操作,需要的朋友可以参考下
    2017-08-08

最新评论