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

网友投稿 402 2023-07-21

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

前言:

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

规划接口列表

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

发送普通邮件

发送html邮件

发送图文邮件

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

接口响应时间比较长

遇到并发的情况,容易导致服务器压力过大或者邮箱服务封ip

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

准备工作

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

org.springframework.boot

spring-boot-starter-mail

com.google.guava

guava

23.0

org.projectlombok

lombok

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);

}

//创建线程池方法

pfqhdQDVjHDrivate 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,

fqhdQDVjHD 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 sendImgMail(@RequestBody Request request) {

Result result = Result.create();

ImgEmailDTO imgEmailDTO=request.getData();

StringBuilder sb=new StringBuilder();

sb.append(imgEmailDTO.getImgContent());

//cid:资源id。在spring中会自动绑定

sb.append("");

imgEmailDTO.setImgContent(sb.toString());

asyncEventBus.post(imgEmailDTO);

return result.success(1);

}

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

下面来做个测试

请求很迅速的返回了结果

然后去邮箱中查看结果

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

总结

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:详解springboot和vue前后端分离开发跨域登陆问题
下一篇:如何在IDEA启动多个Spring Boot工程实例(图文)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~