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

作者:祥哥去哪里啊 时间:2023-07-20 06:58:34 

前言:

发送邮件,肯定是每个公司都会有的基本业务。很多公司都会选择把发送邮件作为一个基础服务,对外提供接口。直接调用就可发邮件了。但是我们都知道发送邮件耗时都比较长。那么今天就介绍下使用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替换。最后将实体类抛入队列。直接返回接口请求。队列那边就会排着队搞定所有的邮件

下面来做个测试

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

请求很迅速的返回了结果

然后去邮箱中查看结果

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

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

来源:https://juejin.im/post/5d79af986fb9a06b1c745908

标签:springboot,邮件,服务
0
投稿

猜你喜欢

  • 结合.net框架在C#派生类中触发基类事件及实现接口事件

    2022-02-23 20:39:57
  • Android多国语言转换Excel及Excel转换为string详解

    2022-10-30 08:07:02
  • java日期操作工具类(获取指定日期、日期转换、相隔天数)

    2023-11-28 06:42:53
  • java批量解析微信dat文件

    2022-12-26 01:53:28
  • Android实现USB扫码枪获取扫描内容

    2023-09-08 00:56:31
  • android使用Path绘制出多边形

    2021-11-11 19:53:38
  • RxJava之网络请求最常见的三种场景

    2023-04-29 19:49:48
  • Android HandlerThread案例详解

    2022-04-20 09:46:25
  • 在Visual Studio上构建C++的GUI框架wxWidgets的开发环境

    2023-04-12 01:02:06
  • hadoop分布式环境搭建过程

    2023-09-23 15:18:50
  • Android学习笔记--使用剪切板在Activity中传值示例代码

    2022-12-21 13:43:58
  • Spring 与 JDK 线程池的简单使用示例详解

    2023-08-20 04:02:59
  • Android 7.0行为变更 FileUriExposedException解决方法

    2023-07-28 01:38:29
  • Java基于余弦方法实现的计算相似度算法示例

    2022-06-29 22:02:13
  • C#使用async和await实现异步编程

    2023-08-23 18:32:52
  • 详细解读java同步之synchronized解析

    2022-08-01 15:27:05
  • Android编程学习之抽象类AbsListView用法实例分析

    2023-03-18 12:19:49
  • RocketMQ源码解析broker 启动流程

    2022-12-25 10:50:54
  • Android图片色彩变换实现方法

    2022-03-21 07:23:32
  • Java内存模型中的虚拟机栈原理分析

    2022-02-08 04:41:33
  • asp之家 软件编程 m.aspxhome.com