Spring Boot 自带的 JavaMail 集成

1、获取邮箱授权码

以QQ邮箱为例,登录QQ邮箱网页版后,点击进入"设置"-"安全设置"选项。

2、集成JavaMail

官方文档:https://docs.spring.io/spring-framework/reference/integration/email.html

2.1、引入依赖

XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

2.2、添加配置

java 复制代码
spring:
  # 邮件配置
  mail:
    # 邮件服务器地址
    host:
    # 邮件发送者
    username:
    # 授权码
    password:
    properties:
      mail:
        smtp:
          # 是否启用 SMTP 验证
          auth: true
          starttls:
            # 是否启用TLS加密
            enable: true

2.3、创建邮箱对象

java 复制代码
@Data
public class Email implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 必填
     * 邮件接收方
     */
    private String[] to;

    /**
     * 必填
     * 邮件主题
     */
    private String subject;

    /**
     * 可选
     * 邮件内容
     */
    private String text;

    /**
     * 可选
     * 附件路径
     */
    private List<String> filePathList;

    /**
     * 可选
     * 图片路径
     */
    private List<String> imagePathList;

}

2.4、邮箱格式校验

java 复制代码
public class EmailUtils {

    // 定义用于匹配大多数有效电子邮件地址的正则表达式
    private static final String EMAIL_REGEX =
            "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";

    // 编译正则表达式
    private static final Pattern emailPattern = Pattern.compile(EMAIL_REGEX);

    /**
     * 校验给定的email是否合法
     * @param email 待校验的电子邮件地址
     * @return 如果电子邮件地址合法返回true,否则返回false
     */
    public static boolean isValidEmail(String email) {
        if (email == null) {
            return false;
        }
        Matcher matcher = emailPattern.matcher(email);
        return matcher.matches();
    }

}

2.5、发送内容为文本的邮件

java 复制代码
@Component
public class SendMail {

    private static final Logger log = LoggerFactory.getLogger(SendMail.class);

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

    @Autowired
    private JavaMailSender javaMailSender;


    /**
     * 发送内容为文本的邮件
     **/
    public boolean sendSimpleMail(Email email) {
        try {
            checkEmail(email);
            //创建简单邮件消息
            SimpleMailMessage message = new SimpleMailMessage();
            //发送人
            message.setFrom(from);
            //接收人
            message.setTo(email.getTo());
            //邮件主题
            message.setSubject(email.getSubject());
            //邮件内容
            message.setText(email.getText());
            //发送邮件
            javaMailSender.send(message);
        } catch (Exception e) {
            log.error("邮件发送失败:{}", email, e);
            return false;
        }
        log.error("邮件发送成功:{}", Arrays.toString(email.getTo()));
        return true;
    }

}

2.6、发送内容为html的邮件

java 复制代码
@Component
public class SendMail {

    private static final Logger log = LoggerFactory.getLogger(SendMail.class);

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

    @Autowired
    private JavaMailSender javaMailSender;


    /**
     * 发送内容为html的邮件
     **/
    public boolean sendMimeMail(Email email) {
        try {
            checkEmail(email);
            //创建MINE邮件消息
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper mineHelper = new MimeMessageHelper(message, true);
            //发送人
            mineHelper.setFrom(from);
            //接收人
            mineHelper.setTo(email.getTo());
            //邮件主题
            mineHelper.setSubject(email.getSubject());
            //邮件内容,true 表示带有附件或html
            mineHelper.setText(email.getText(),true);
            //发送邮件
            javaMailSender.send(message);
        } catch (Exception e) {
            log.error("邮件发送失败:{}", email, e);
            return false;
        }
        log.error("邮件发送成功:{}", Arrays.toString(email.getTo()));
        return true;
    }

}

2.7、发送内容为图片的邮件

内联资源通过使用指定的Content-ID添加到MimeMessage。添加文本和资源的顺序非常重要。一定要先添加文本,然后再添加资源。如果你用另一种方式来做,它是行不通的。

java 复制代码
@Component
public class SendMail {

    private static final Logger log = LoggerFactory.getLogger(SendMail.class);

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

    @Autowired
    private JavaMailSender javaMailSender;


    /**
     * 发送内容为图片的邮件
     **/
    public boolean sendImageMail(Email email) {
        try {
            checkEmail(email);
            //创建MINE邮件消息
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper mineHelper = new MimeMessageHelper(message, true);
            //发送人
            mineHelper.setFrom(from);
            //接收人
            mineHelper.setTo(email.getTo());
            //邮件主题
            mineHelper.setSubject(email.getSubject());
            if (CollectionUtils.isNotEmpty(email.getImagePathList())) {
                StringBuilder htmlContent = new StringBuilder();
                htmlContent.append("<html><body>");
                for(int i = 0; i < email.getImagePathList().size(); i++){
                    String imagePath = email.getImagePathList().get(i);
                    File file = new File(imagePath);
                    if (!file.exists()) {
                        log.error("图片不存在:{}", imagePath);
                        continue;
                    }
                    String contentId = "identifier" + i;
                    htmlContent.append("<img src='cid:").append(contentId).append("' style='max-width:600px;display:block;margin-bottom:10px;'/>");
                }
                htmlContent.append("</body></html>");
                //邮件内容,true 表示带有附件或html
                mineHelper.setText(htmlContent.toString(),true);
                for(int i = 0; i < email.getImagePathList().size(); i++){
                    String imagePath = email.getImagePathList().get(i);
                    File file = new File(imagePath);
                    if (!file.exists()) {
                        log.error("图片不存在:{}", imagePath);
                        continue;
                    }
                    //添加内联资源,一个id对应一个资源,最终通过id来找到该资源
                    String contentId = "identifier" + i;
                    FileSystemResource resource = new FileSystemResource(file);
                    mineHelper.addInline(contentId, resource);
                }
            }
            //发送邮件
            javaMailSender.send(message);
        } catch (Exception e) {
            log.error("邮件发送失败:{}", email, e);
            return false;
        }
        log.error("邮件发送成功:{}", Arrays.toString(email.getTo()));
        return true;
    }

}

2.7、发送内容为文本且包含图片的邮件

java 复制代码
@Component
public class SendMail {

    private static final Logger log = LoggerFactory.getLogger(SendMail.class);

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

    @Autowired
    private JavaMailSender javaMailSender;


     /**
     * 发送内容为文本且包含图片的邮件
     **/
    public boolean sendTextImageMail(Email email) {
        try {
            checkEmail(email);
            //创建MINE邮件消息
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper mineHelper = new MimeMessageHelper(message, true);
            //发送人
            mineHelper.setFrom(from);
            //接收人
            mineHelper.setTo(email.getTo());
            //邮件主题
            mineHelper.setSubject(email.getSubject());
            if (CollectionUtils.isNotEmpty(email.getImagePathList())) {
                StringBuilder htmlContent = new StringBuilder();
                htmlContent.append("<html><body>");
                htmlContent.append("<div>").append(email.getText()).append("</div>");
                for(int i = 0; i < email.getImagePathList().size(); i++){
                    String imagePath = email.getImagePathList().get(i);
                    File file = new File(imagePath);
                    if (!file.exists()) {
                        log.error("图片不存在:{}", imagePath);
                        continue;
                    }
                    String contentId = "identifier" + i;
                    htmlContent.append("<img src='cid:").append(contentId).append("' style='max-width:600px;display:block;margin-bottom:10px;'/>");
                }
                htmlContent.append("</body></html>");
                //邮件内容,true 表示带有附件或html
                mineHelper.setText(htmlContent.toString(),true);
                for(int i = 0; i < email.getImagePathList().size(); i++){
                    String imagePath = email.getImagePathList().get(i);
                    File file = new File(imagePath);
                    if (!file.exists()) {
                        log.error("图片不存在:{}", imagePath);
                        continue;
                    }
                    //添加内联资源,一个id对应一个资源,最终通过id来找到该资源
                    String contentId = "identifier" + i;
                    FileSystemResource resource = new FileSystemResource(file);
                    mineHelper.addInline(contentId, resource);
                }
            }else{
                mineHelper.setText(email.getText());
            }
            //发送邮件
            javaMailSender.send(message);
        } catch (Exception e) {
            log.error("邮件发送失败:{}", email, e);
            return false;
        }
        log.error("邮件发送成功:{}", Arrays.toString(email.getTo()));
        return true;
    }

}

2.8、发送带附件的邮件

java 复制代码
@Component
public class SendMail {

    private static final Logger log = LoggerFactory.getLogger(SendMail.class);

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

    @Autowired
    private JavaMailSender javaMailSender;


    /**
     * 发送带附件的邮件
     * 邮件内容可以为文本或html
     **/
    public boolean sendAttachmentMail(Email email) {
        try {
            checkEmail(email);
            //创建MINE邮件消息
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper mineHelper = new MimeMessageHelper(message, true);
            //发送人
            mineHelper.setFrom(from);
            //接收人
            mineHelper.setTo(email.getTo());
            //邮件主题
            mineHelper.setSubject(email.getSubject());
            //邮件内容,true 表示带有附件或html
            mineHelper.setText(email.getText(),true);
            // 添加附件
            if (CollectionUtils.isNotEmpty(email.getFilePathList())) {
                for (String filePath : email.getFilePathList()) {
                    File file = new File(filePath);
                    if (!file.exists()) {
                        log.error("附件不存在:{}", filePath);
                        continue;
                    }
                    FileSystemResource resource = new FileSystemResource(file);
                    mineHelper.addAttachment(Objects.requireNonNull(resource.getFilename()), resource);
                }
            }
            //发送邮件
            javaMailSender.send(message);
        } catch (Exception e) {
            log.error("邮件发送失败:{}", email, e);
            return false;
        }
        log.error("邮件发送成功:{}", Arrays.toString(email.getTo()));
        return true;
    }

}

2.9、checkEmail方法

java 复制代码
    /**
     * 校验邮件
     **/
    private static boolean checkEmail(Email email) {
        log.error("开始发送邮件:{}", email);
        if (email == null) {
            log.error("邮件参数错误:{}", (Object) null);
            return false;
        }
        if (email.getTo() == null || email.getTo().length == 0) {
            log.error("邮件接收人不能为空:{}", email);
            return false;
        }
        if (StringUtils.isEmpty(email.getSubject())) {
            log.error("邮件主题不能为空:{}", email);
            return false;
        }
        for (String to : email.getTo()) {
            if (!EmailUtils.isValidEmail(to)) {
                log.error("邮件接收人格式错误:{}", to);
                return false;
            }
        }
        return true;
    }

3、在业务中怎么使用

在其他服务中直接注入SendMail即可

java 复制代码
@Autowired
private SendMail sendMail;

3.1、发送内容为文本的邮件

java 复制代码
Email email = new Email();
email.setTo(new String[]{"ceshi@qq.com"});
email.setSubject("测试邮件");
email.setText("测试邮件");
boolean b = sendMail.sendSimpleMail(email);
System.out.println(b);

3.2、发送内容为html的邮件

java 复制代码
Email email = new Email();
email.setTo(new String[]{"ceshi@qq.com"});
email.setSubject("测试邮件");
email.setText("<html><body><h1>测试邮件</h1></body></html>");
boolean b = sendMail.sendMimeMail(email);
System.out.println(b);

3.3、发送内容为图片的邮件

java 复制代码
Email email = new Email();
email.setTo(new String[]{"ceshi@qq.com"});
email.setSubject("测试邮件");
email.setImagePathList(Arrays.asList("c:\\ceshi.jpg");
boolean b = sendMail.sendImageMail(email);
System.out.println(b);

3.4、发送内容为文本且包含图片的邮件

java 复制代码
Email email = new Email();
email.setTo(new String[]{"ceshi@qq.com"});
email.setSubject("测试邮件");
email.setText("测试邮件");
email.setImagePathList(Arrays.asList("c:\\ceshi.jpg");
boolean b = sendMail.sendTextImageMail(email);
System.out.println(b);

3.5、发送带附件的邮件

java 复制代码
Email email = new Email();
email.setTo(new String[]{"ceshi@qq.com"});
email.setSubject("测试邮件");
email.setText("测试邮件");
email.setFilePathList(Arrays.asList("c:\\ceshi.jpg");
boolean b = sendMail.sendAttachmentMail(email);
System.out.println(b);
相关推荐
JosieBook3 小时前
【SpringBoot】21-Spring Boot中Web页面抽取公共页面的完整实践
前端·spring boot·python
刘一说3 小时前
Spring Boot+Nacos+MySQL微服务问题排查指南
spring boot·mysql·微服务
叫我阿柒啊7 小时前
从Java全栈到云原生:一场技术深度对话
java·spring boot·docker·微服务·typescript·消息队列·vue3
计算机毕设定制辅导-无忧学长8 小时前
MQTT 与 Java 框架集成:Spring Boot 实战(一)
java·网络·spring boot
叫我阿柒啊8 小时前
从Java全栈到Vue3实战:一次真实面试的深度复盘
java·spring boot·微服务·vue3·响应式编程·前后端分离·restful api
泉城老铁8 小时前
Spring Boot中实现多线程分片下载
java·spring boot·后端
泉城老铁8 小时前
Spring Boot中实现多文件打包下载
spring boot·后端·架构
泉城老铁8 小时前
Spring Boot中实现大文件分片下载和断点续传功能
java·spring boot·后端
友莘居士8 小时前
长流程、复杂业务流程分布式事务管理实战
spring boot·rocketmq·saga·复杂流程分布式事务·长流程
百思可瑞教育8 小时前
Spring Boot 参数校验全攻略:从基础到进阶
运维·服务器·spring boot·后端·百思可瑞教育·北京百思教育