Spring Boot学习笔记(十八)Spring Boot发送各种类型的邮件

Spring Boot 发送简单邮件、HTML5邮件、图片邮件、带附件的邮件以及thymeleaf模版邮件

spring-boot-starter-mail

  • 网站发送邮件最早使用 JavaMail相关 API 来写发送邮件的相关代码,后来 Spring 推出了 JavaMailSender 简化了邮件发送代码的编写。现在Spring Boot 在 JavaMailSender 的基础上又进行了封装,就有了现在的 spring-boot-starter-mail
  • Spring 的 JavaMailSenderImpl 提供了强大的邮件发送功能,可发送普通文本邮件、带附件邮件、HTML格式邮件、带图片邮件,设置发送内容编码格式、设置发送人的显示名称

JavaMail API 按功能可分为如下三大类:

  • Message 类 :创建和解析邮件的核心 API,用于创建一封邮件,可以设置发件人、收件人、邮件主题、正文信息、发送时间等信息
  • Transport 类:发送邮件的核心 API 类
  • Store 类:接收邮件的核心API类

邮件的相关协议

  • SMTP 协议:发送邮件协议
  • POP3 协议:获取邮件协议;
  • IMAP:接收信息的高级协议;
  • MIME:邮件拓展内容格式:信息格式,附件格式

图示互相发送邮件的过程
在这里插入图片描述

初始化项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我演示的是QQ邮箱,所以先把QQ邮箱的SMTP和POP3服务等开起来在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
记住这个授权码

项目结构

在这里插入图片描述
pom.xml导入以下依赖:

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

application.properties做如下配置,需要将 spring.mail.username 和 spring.mail.password 改成自己邮箱对应的登录名和是开启 POP3 之后设置的客户端授权密码

spring.mail.host=smtp.qq.com
spring.mail.username=你的QQ邮箱号@qq.com
spring.mail.password=刚刚的授权码
spring.mail.default-encoding=UTF-8

MailService.java

package wen.mail.service;

public interface MailService {

    public void sendSimpleMail(String to, String subject, String content);

    public void sendHtmlMail(String to, String subject, String content);

    public void sendAttachmentsMail(String to, String subject, String content, String filePath);

    public void sendInlineResourcesMail(String to, String subject, String content, String srcPath, String srcId);
}

实现类MailServiceImpl.java

package wen.mail.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 wen.mail.service.MailService;

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

@Component
public class MailServiceImpl implements MailService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private JavaMailSender mailSender;

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

    /**
     * 发送简单邮件
     * @param to
     * @param subject
     * @param content
     */
    @Override
    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);

        try {
            mailSender.send(message);
            logger.info("邮件已发送");
        } catch (Exception e) {
            logger.error("异常!", e);
        }
    }

    /**
     * 发送带 HTML 模板的邮件
     * @param to
     * @param subject
     * @param content
     */
    @Override
    public void sendHtmlMail(String to, String subject, String content) {

        MimeMessage message = mailSender.createMimeMessage();

        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            //true 表示创建一个 multipart message
            helper.setText(content, true);
            mailSender.send(message);
            logger.info("html 邮件发送成功!");
        } catch (MessagingException e) {
            logger.error("HTML 邮件异常!", e);
        }
    }

    /**
     * 发送带附件的邮件
     * @param to
     * @param subject
     * @param content
     * @param filePath
     */
    @Override
    public void sendAttachmentsMail(String to, String subject, String content, String filePath) {

        MimeMessage message = mailSender.createMimeMessage();

        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);

            FileSystemResource file = new FileSystemResource(new File((filePath)));
            String fileName = file.getFilename();
            helper.addAttachment(fileName, file);
            mailSender.send(message);
            logger.info("带附件的邮件已发送");
        } catch (MessagingException e) {
            logger.error("发送附件异常!", e);
        }
    }

    /**
     * 发送带静态资源的邮件
     * @param to
     * @param subject
     * @param content
     * @param srcPath
     * @param srcId
     */
    @Override
    public void sendInlineResourcesMail(String to, String subject, String content, String srcPath, String srcId) {
        MimeMessage message = mailSender.createMimeMessage();

        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);

            FileSystemResource res = new FileSystemResource(new File(srcPath));
            helper.addInline(srcId, res);

            mailSender.send(message);
            logger.info("嵌入静态资源的邮件已经发送。");

        } catch (MessagingException e) {
            logger.error("发送嵌入静态资源的邮件时发生异常!", e);
        }
    }
}

测试类 MailApplicationTests.java

package wen.mail;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import wen.mail.service.MailService;

@SpringBootTest
class MailApplicationTests {

    @Autowired
    private MailService mailService;

    @Test
    public void testSimpleMail() throws Exception {
        mailService.sendSimpleMail(" your QQ number @qq.com", "The Simple Mail", "Good afternoon, Stephanie!");
    }

    @Test
    public void testHtmlMail() throws Exception {
        String content = "<html>\n" + "<body>\n" + " <h6>it is a mail from html mail form</h6>\n" + "</body>\n" + "</html>";
        mailService.sendHtmlMail(" your QQ number @qq.com", "HTML mail", content);
    }

    @Test
    public void sendAttachmentsMail() {
        String filepath = "附件的存储路径";
        mailService.sendAttachmentsMail(" your QQ number @qq.com", "script", "speech", filepath);
    }

    @Test
    public void sendInlineResourceMail() {
        String srcId = "Stephanie";
        String content = "<html><body>图片邮件:<img src=\'id:" + srcId + "\' ></body></html>";
        String imgPath = "图片在电脑的存储路径 -- 1.jpg";
        mailService.sendInlineResourcesMail(" your QQ number @qq.com", "image mail", content, imgPath, srcId);
    }

}

发送简单邮件

  • from:邮件发送者
  • to:邮件接收者
  • subject:邮件主题
  • content:邮件的主体
    -
    在这里插入图片描述

发送 HTML 格式邮件

  • 发送邮件使用 MimeMessageHelper 类,MimeMessageHelper 支持发送复杂邮件模板,支持文本、附件、HTML、图片等,接下来会继续使用
    在这里插入图片描述
    在这里插入图片描述

发送带附件的邮件

  • 添加多个附件可以使用条 helper.addAttachment(fileName, file)
  • 附件可以是图片、压缩包、Word 等任何文件,但是邮件厂商一般都会对附件大小有限制,太大的附件可以使用网盘上传后,在邮件中给出链接
    在这里插入图片描述
    在这里插入图片描述
    发送静态资源邮件
  • 添加多个图片可以使用多条 和helper.addInline(rscId, res) 来实现
    在这里插入图片描述
    在这里插入图片描述
    这里我明明发的是图片,但是发送过来之后就变成bin了,但是我下载之后改后缀为 .jpg 就没问题
    在这里插入图片描述
模版邮件

小声BB:我在原来那个项目下建立模版邮件老师出一些很奇妙的BUG,所以我干脆新建项目
在这里插入图片描述
pom.xml 导入以下依赖:

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

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

在项目的 resources下面 template 建立mail 包,再建立mail.html文件写邮件模版

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>title</title>
</head>
<body>
<h3>Template mail <span style="font-size: 35px" th:text="${username}"></span></h3>
</body>
</html>

application.properties

spring.mail.host=smtp.qq.com
spring.mail.username=your QQ number @qq.com
spring.mail.password=之前的授权码
spring.mail.default-encoding=UTF-8
# thymeleaf配置
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=utf-8
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/

MailDo.java

package wen.templatemail.domain;

import java.util.Map;

public class MailDo {

    private String title;
    private String content;
    private String email;
    private Map<String, Object> attachment;

    public MailDo() {
    }

    public MailDo(String title, String content, String email) {
        this.title = title;
        this.content = content;
        this.email = email;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Map<String, Object> getAttachment() {
        return attachment;
    }

    public void setAttachment(Map<String, Object> attachment) {
        this.attachment = attachment;
    }
}

MailService.java

package wen.templatemail.service;

import wen.templatemail.domain.MailDo;

public interface MailService {

    void sendTemplateMail(MailDo mailDo);

}

MailServiceImpl.java

package wen.templatemail.service.impl;

import wen.templatemail.domain.MailDo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import wen.templatemail.service.MailService;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

@Service
public class MailServiceImpl implements MailService {

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

    @Autowired
    private TemplateEngine templateEngine;

    @Autowired
    private JavaMailSender javaMailSender;

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

    @Async
    @Override
    public void sendTemplateMail(MailDo mailDo) {
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);

            messageHelper.setFrom(from);
            messageHelper.setTo(mailDo.getEmail());
            messageHelper.setSubject(mailDo.getTitle());

            Context context = new Context();
            context.setVariables(mailDo.getAttachment());

            String emailContent = templateEngine.process("/mail/mail", context);

            messageHelper.setText(emailContent, true);
            javaMailSender.send(mimeMessage);

        } catch (MessagingException e) {
            log.error("模板邮件发送失败->message:{}", e.getMessage());
        }
    }
}

MailController.java

package wen.templatemail.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import wen.templatemail.domain.MailDo;
import wen.templatemail.service.MailService;

import java.util.HashMap;
import java.util.Map;

@Controller
public class MailController {

    @Autowired
    private MailService mailService;

    @GetMapping("/templateMail")
    public void mail() {
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("username", "test");
            MailDo mailDo = new MailDo("template mail", "", "820352756@qq.com");
            mailDo.setAttachment(map);
            mailService.sendTemplateMail(mailDo);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

开启项目 TemplatemailApplication 浏览器访问 http://localhost:8080/templateMail
运行结果:
在这里插入图片描述
邮件发送失败

  • 因为各种原因,总会有邮件发送失败的情况,如邮件发送过于频繁、网络异常等。在出现这种情况的时候我们一般会考虑重新重试发送邮件,会分为以下几个步骤来实现:
  • 接收到发送邮件请求,首先记录请求并且入库调用邮件发送接口发送邮件,并且将发送结果记录入库。
  • 启动定时系统扫描时间段内,未发送成功并且重试次数小于 3 次的邮件,进行再次发送

异步发送

  • 很多时候邮件发送并不是我们主业务必须关注的结果,比如通知类、提醒类的业务可以允许延时或者失败。
  • 这个时候可以采用异步的方式来发送邮件,加快主交易执行速度,在实际项目中可以采用 MQ 发送邮件相关参数,监听到消息队列之后启动发送邮件

总结

  • 使用 Spring Boot 集成发送邮件的功能非常简单,只需要简单编码就可以实现发送普通文本邮件、带附件邮件、HTML 格式邮件、带图片邮件等
  • 如果需要做成一个邮件系统还需要考虑很多因素,如邮箱发送失败重试机制、防止邮件被识别为垃圾邮件,固定时间内发送邮件的限制等
  • 在微服务架构中,常常将一些基础功能下沉下来,作为独立的服务来使用,邮件系统作为一种和具体业务无关的功能,特别适合做为独立的微服务来支持整个系统
发布了77 篇原创文章 · 获赞 26 · 访问量 2万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 像素格子 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览