Spring boot搭建邮件服务的完整步骤

前言:

发送邮件,肯定是每个公司都会有的基本业务。很多公司都会选择把发送邮件作为一个基础服务,对外提供接口。直接调用就可发邮件了。但是我们都知道发送邮件耗时都比较长。那么今天就介绍下使用Spring boot+eventbus来打造一个简单邮件服务

规划接口列表

发送邮件的类型准备的有三种

  • 发送普通邮件
  • 发送html邮件
  • 发送图文邮件

还有一个细节,如果我们同步的取发送邮件会有两个问题。

  • 接口响应时间比较长
  • 遇到并发的情况,容易导致服务器压力过大或者邮箱服务封ip

所以我们准备使用队列来执行发送邮件的操作。可以解决这个问题。队列我选用的是Google的eventbus。是一款很轻量的队列。直接走的内存

准备工作

首先要在pom.xml中引入 需要使用的包

 <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-mail</artifactId>
 </dependency>
 <dependency>
   <groupId>com.google.guava</groupId>
   <artifactId>guava</artifactId>
   <version>23.0</version>
  </dependency>
  <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
  </dependency>
  • spring-boot-starter-mail :spring-boot提供的发邮件的maven库
  • guava:google提供的开源库。里面包含来很多工具
  • lombok:可以帮你省去编写实体类的工具

引入之后,我们还需要配置发送邮件所需要的必要配置

在application.properties中配置邮箱

spring.mail.host=smtp.mail.me.com //邮箱发送服务器
spring.mail.port=587//服务器端口
spring.mail.username=xxx6666@icloud.com//发件人邮箱
spring.mail.password=password//客户端专用密码
//如果和我一样使用的icloud邮箱 还需要下列两个配置,别的有的邮箱不需要
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

做到这里其实就已经完成了,发邮件所需要的配置了。但是我们是要用队列来发送,所以还需要配置下队列

@Configuration
public class AsyncEventBusConfig {
 //实例化bean,采用单例形式注入容器
 @Bean
 @Scope("singleton")
 public AsyncEventBus asyncEventBus(){
  //创建线程池对象
  final ThreadPoolExecutor executor=executor();
  return new AsyncEventBus(executor);
 }
 //创建线程池方法
 private ThreadPoolExecutor executor(){
  return new
    ThreadPoolExecutor(2,
    2,0L,
    TimeUnit.MICROSECONDS,
    new LinkedBlockingQueue<>());
 }
}

封装EmailService

准备好了之后,就可以直接来封装发送邮件的业务了。之前有提到我们需要三个接口,同样的,我们也需要三个service方法

@Service
public class EmailService {

 @Autowired
 private JavaMailSender javaMailSender;

 /**
  * 发件人。这里发件人一般是同使用的发件邮箱一致
  */
 @Value("${spring.mail.username}")
 private String from;

 /**
  * 发送文本邮件
  * @param to 收件人邮箱地址
  * @param subject 主题
  * @param content 内容
  */
 public void sendTextMail(String to,
        String subject,
        String content) {
  SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
  simpleMailMessage.setTo(to);
  simpleMailMessage.setSubject(subject);
  simpleMailMessage.setText(content);
  simpleMailMessage.setFrom(from);
  javaMailSender.send(simpleMailMessage);
 }

 /**
  * 发送html内容的邮件
  * @param to 收件人
  * @param htmlContent html内容
  * @param subject 主题
  * @throws MessagingException
  */
 public void sendHtmlMail(String to,
        String htmlContent,
        String subject) throws MessagingException {
  MimeMessage message = javaMailSender.createMimeMessage();
  MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
  messageHelper.setTo(to);
  messageHelper.setSubject(subject);
  messageHelper.setFrom(from);
  messageHelper.setText(htmlContent, true);
  javaMailSender.send(message);
 }

 /**
  * 发送图文邮件
  * @param to 收件人
  * @param imgContent 图文内容
  * @param subject 主题
  * @param rscId 资源id
  * @param imgPath 资源路径
  * @throws MessagingException
  */
 public void sendImgMail(String to,
       String imgContent,
       String subject,
       String rscId,
       String imgPath) throws MessagingException {
  MimeMessage message = javaMailSender.createMimeMessage();
  MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
  messageHelper.setTo(to);
  messageHelper.setSubject(subject);
  messageHelper.setFrom(from);
  messageHelper.setText(imgContent, true);
  messageHelper.addInline(rscId, new File(imgPath));
  javaMailSender.send(message);
 }
}

队列监听

既然封装好了方法,那么就需要调用。调用的方式,其实就是将接口传来的数据传到队列里。队列的消费者接收到了消息就将消息拿来调用发送邮件的方法

我们首先创建一个消费类,用来接受消息,处理消息。

@Service
public class EventBusListener {

 /**
  * 引入bean
  */
 @Autowired
 private AsyncEventBus asyncEventBus;

 @Autowired
 private EmailService emailService;

 /**
  * 注册服务类
  */
 @PostConstruct
 public void init(){
  asyncEventBus.register(this);
 }

 /**
  * 线程安全,消费 文本消息
  * @param textEmailDTO
  */
 @AllowConcurrentEvents
 @Subscribe
 public void sendTextMail(TextEmailDTO textEmailDTO){
  emailService.sendTextMail(
    textEmailDTO.getTo(),
    textEmailDTO.getSubject(),
    textEmailDTO.getContent()
  );
 }

 /**
  * 线程安全 消费 html消息
  * @param htmlEmailDTO
  */
 @AllowConcurrentEvents
 @Subscribe
 public void sendHtmlMail(HtmlEmailDTO htmlEmailDTO){
  try {
   emailService.sendHtmlMail(
     htmlEmailDTO.getTo(),
     htmlEmailDTO.getHtmlContent(),
     htmlEmailDTO.getSubject()
   );
  } catch (MessagingException e) {
   // nothing to do
  }
 }

 /**
  * 线程安全 消费 图文消息
  * @param imgEmailDTO
  */
 @AllowConcurrentEvents
 @Subscribe
 public void sendImgMail(ImgEmailDTO imgEmailDTO){
  try {
   emailService.sendImgMail(
     imgEmailDTO.getTo(),
     imgEmailDTO.getImgContent(),
     imgEmailDTO.getSubject(),
     imgEmailDTO.getRscId(),
     imgEmailDTO.getImgPath()
   );
  } catch (MessagingException e) {
   // nothing to do
  }
 }
}

其实eventbus抛消息都是使用的post方法来抛消息。走到不同的方法里面是利用了类的多态,抛入不同的实体类就可以进行区分了。走进了不同的方法,就调用相应Service方法。

控制器与测试

控制器部分,没什么好说的,我就贴出图文的代码。其余代码可以在我的github上面看

先看眼实体类

@Data
public class ImgEmailDTO implements Serializable {
 public ImgEmailDTO() {
 }

 /**
  * 图片路径
  */
 private String imgPath;

 /**
  * 资源id
  */
 private String rscId;

 /**
  * 主题
  */
 private String subject;

 /**
  * 图片正文(同样可以使用html)
  */
 private String imgContent;

 /**
  * 收件人
  */
 private String to;
}
 /**
  * 发送图文邮件
  * @param request
  * @return
  */
 @RequestMapping(value = "/sendImgMail", method = RequestMethod.POST)
 public Result<Integer> sendImgMail(@RequestBody Request<ImgEmailDTO> request) {
  Result<Integer> result = Result.create();
  ImgEmailDTO imgEmailDTO=request.getData();
  StringBuilder sb=new StringBuilder();
  sb.append(imgEmailDTO.getImgContent());
  //cid:资源id。在spring中会自动绑定
  sb.append("<img src=\'cid:").append(imgEmailDTO.getRscId()).append("\'></img>");
  imgEmailDTO.setImgContent(sb.toString());
  asyncEventBus.post(imgEmailDTO);
  return result.success(1);
 }

图文要稍微特殊一点,需要拼接下正文内容。然后将实体类中的content替换。最后将实体类抛入队列。直接返回接口请求。队列那边就会排着队搞定所有的邮件

下面来做个测试

请求很迅速的返回了结果

然后去邮箱中查看结果

好了今天对邮件服务的介绍就写到这里。知识点并不深奥,主要介绍一个思路。如有不对的地方,请大神指出。谢谢

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • Spring Boot实现邮件服务(附:常见邮箱的配置)

    前言 发送邮件应该是网站的必备功能之一,什么注册验证,忘记密码或者是给用户发送营销信息.最早期的时候我们会使用JavaMail相关api来写发送邮件的相关代码,后来spring退出了JavaMailSender更加简化了邮件发送的过程,在之后springboot对此进行了封装就有了现在的spring-boot-starter-mail,本文将详细给大家介绍了关于Spring Boot邮件服务的相关内容,下面话不多说了,来一起看看详细的介绍吧 1. pom.xml文件中引入依赖 <dependen

  • 详解Spring Boot Admin监控服务上下线邮件通知

    本文介绍了Spring Boot Admin监控服务上下线邮件通知,分享给大家,具体如下: 微服务架构下,服务的数量少则几十,多则上百,对服务的监控必不可少. 如果是以前的单体项目,启动了几个项目是固定的,可以通过第三方的监控工具对其进行监控,然后实时告警. 在微服务下,服务数量太多,并且可以随时扩展,这个时候第三方的监控功能就不适用了,我们可以通过Spring Boot Admin连接注册中心来查看服务状态,这个只能在页面查看. 很多时候更希望能够自动监控,通过邮件告警,某某服务下线了这样的功

  • Spring Boot整合邮件发送与注意事项

    什么是Spring Boot Spring Boot是一个框架,其设计目的是简化Spring应用的初始搭建配置以及开发过程.该框架使用了特定的配置方式,从而使开发人员不在需要定义样板化的配置. Spring Boot的好处 1.配置简单: 2.编码简单: 3.部署简单: 4.监控简单: 概述 Spring Boot下面整合了邮件服务器,使用Spring Boot能够轻松实现邮件发送:整理下最近使用Spring Boot发送邮件和注意事项: Maven包依赖 <dependency> <g

  • Spring Boot实战之发送邮件示例代码

    一.邮件服务简介 邮件服务在互联网早期就已经出现,如今已成为人们互联网生活中必不可少的一项服务.那么邮件服务是怎么工作的呢?如下给出邮件发送与接收的典型过程: 1.发件人使用SMTP协议传输邮件到邮件服务器A: 2.邮件服务器A根据邮件中指定的接收者,投送邮件至相应的邮件服务器B: 3.收件人使用POP3协议从邮件服务器B接收邮件. SMTP(Simple Mail Transfer Protocol)是电子邮件(email)传输的互联网标准,定义在RFC5321,默认使用端口25: POP3(

  • SpringBoot中发送QQ邮件功能的实现代码

    本文是vhr系列的第十二篇,项目地址 https://github.com/lenve/vhr 邮件发送也是一个老生常谈的问题了,代码虽然简单,但是许多小伙伴对过程不太理解,所以还是打算和各位小伙伴聊聊这个话题. 邮件协议 我们经常会听到各种各样的邮件协议,比如SMTP.POP3.IMAP,那么这些协议有什么作用,有什么区别?我们先来讨论一下这个问题. SMTP是一个基于TCP/IP的应用层协议,江湖地位有点类似于HTTP,SMTP服务器默认监听的端口号为25.看到这里,小伙伴们可能会想到既然S

  • Spring Boot实现邮件注册功能示例代码

    注册流程 1.[前端] 用户在注册页面提交注册信息: 2.[后端] 校验用户提交的参数,有误直接返回错误信息,无误向下执行: 3.[后端] 随机生成一个ID,将ID作为key,用户信息作为value,存入redis,设置时长: 4.[后端] 生成激活链接,通过邮件系统发送邮件到用户邮箱 5.[前端] 用户点击上图的"确认注册": 6.[后端] 校验value是否过期,校验邮箱是否已经注册,没有则保存用户信息到数据库,提示用户已经注册成功: 功能实现(逆向分析) 1.先看看邮件发送的实现

  • SpringBoot使用FreeMarker模板发送邮件

    本文实例为大家分享了SpringBoot +Mail+FreeMarker发送邮件,供大家参考,具体内容如下 通过spirngboot 自带的mail服务及FreeMarker模板引擎,发送邮 添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </depen

  • Spring Boot中利用JavaMailSender发送邮件的方法示例(附源码)

    快速入门 在Spring Boot的工程中的pom.xml中引入spring-boot-starter-mail依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> 如其他自动化配置模块一样,在完成了依赖引入之后,只需要在applicatio

  • Spring Boot实现邮件发送功能

    本文实例为大家分享了Spring Boot邮件发送功能的具体代码,供大家参考,具体内容如下 1.引入依赖 <!-- mail依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> 2.参数配置 在application.pro

  • Spring Boot发送邮件详解

    Spring框架使用JavaMailSender接口为发送邮件提供了一个简单的抽象,并且Spring Boot也为它提供了自动配置和一个starter模块. 如果spring.mail.host和相关的库(通过spring-boot-starter-mail定义)都存在,一个默认的JavaMailSender将被创建.该sender可以通过spring.mail命名空间下的配置项进一步自定义,下面本站素文宅博客具体讲述一下Spring Boot如何实现发送邮件. 引入spring-boot-st

随机推荐