准备rabbitmq服务
我前面有个安装docker的帖子,如果想省事又快捷的安装rabbitmq请先安装docker,如果你想在自己的Linux机器里直接安装也不是不行,但是你要做好被烦死的准备。https://blog.csdn.net/Curtisjia/article/details/104186314
OK,这里我已经假设你的docker环境没有任何问题了,然后开始拉rabbitmq的镜像,命令如下:
docker run -d --hostname my-rabbit --name leo-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management
说明:
-d 后台运行容器;
–name 指定容器名(自己命名);
–hostname 主机名(RabbitMQ的一个重要注意事项是它根据所谓的 “节点名称” 存储数据,默认为主机名);
完了之后,输入docker ps,能看到自己的镜像启动就OK了。
然后去页面输入 服务端IP :15672
什么,你不会查看自己的服务端IP?ifconfig去查看,(开玩笑,能学到这个层次的人,怎么可能还会有不会看IP的呢)。
然后回车
抱歉我这里是登陆过的,你那边应该会让你登陆,用户名和密码默认都是guest。
后台邮件服务端准备
先导入必要依赖
web、rabbitmq、mail、thymeleaf
开启邮件服务,我这里选的是QQ邮箱
之后你的得到一串密码,要保存好,那就是你登陆邮箱的密码,待会会用到。
开始写配置文件
server.port=8082
spring.mail.host=smtp.qq.com
spring.mail.protocol=smtp
spring.mail.default-encoding=UTF-8
spring.mail.password=这个写邮箱那边给你的密码,别写QQ密码
spring.mail.username=自己的QQ邮箱
spring.mail.port=465
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.debug=true //邮件发送成功的话
//会打印在控制台,这步可以考虑不要
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.host=服务端IP
spring.rabbitmq.port=5672 //这里端口是5672,不要写15672,否则会报错
准备前端发送的邮件模板
老样子,在resources文件夹下创建templates文件夹,必须是templates否则springboot识别不到,当然你也可以在配置文件里改,我觉得没必要。
然后创建一个mail.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>入职欢迎邮件</title>
</head>
<body>
欢迎 <span th:text="${name}"></span>加入我们!你的入职信息如下:
<table border="1">
<tr>
<td>姓名</td>
<td th:text="${name}"></td>
</tr>
<tr>
<td>职位</td>
<td th:text="${posName}"></td>
</tr>
<tr>
<td>职称</td>
<td th:text="${joblevelName}"></td>
</tr>
<tr>
<td>部门</td>
<td th:text="${departmentName}"></td>
</tr>
</table>
<p>希望在未来的日子里,携手共进!</p>
</body>
</html>
开始搭建服务端
一、创建队列
@Bean
Queue queue(){
return new Queue("leo.mail.welcome");
}
这里写在了主函数里,创建一个叫这么个名字的队列。
装逼的点开源码,然后发现没看懂,果断close,进行下一步;
二、创建邮件发送的类MailReceiver
先贴源码:
package com.leo.mailserver.receiver;
import com.leo.vhr.model.Employee;
import com.leo.vhr.model.Hr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Date;
/**
* @description:
* @author: Leo
* @createDate: 2020/2/6
* @version: 1.0
*/
@Component
public class MailReceiver
{
public static final Logger log= LoggerFactory.getLogger(MailReceiver.class);
@Autowired
JavaMailSender javaMailSender;
@Autowired
MailProperties mailProperties;
@Autowired
TemplateEngine templateEngine;
@RabbitListener(queues = "leo.mail.welcome")
public void handler(Employee employee){
//log.info(employee.toString());
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
try
{
helper.setTo(employee.getEmail());
helper.setFrom(mailProperties.getUsername());
helper.setSubject("入职欢迎邮件");
helper.setSentDate(new Date());
Context context = new Context();
context.setVariable("name",employee.getName());
context.setVariable("posName",employee.getPosition().getName());
context.setVariable("joblevelName",employee.getJobLevel().getName());
context.setVariable("departmentName",employee.getDepartment().getName());
String mail = templateEngine.process("mail", context);
helper.setText(mail,true);
javaMailSender.send(mimeMessage);
}
catch (MessagingException e)
{
e.printStackTrace();
log.error("邮件发送失败!"+e.getMessage());
}
}
}
- @RabbitListener(queues = “leo.mail.welcome”)
选择监听的队列 - 注入JavaMailSender
javaMailSender.createMimeMessage();//创建消息对象
- 实现MimeMessageHelper对象,并把消息对象传入捡来
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
然后就是从哪来到哪去,主题、发送时间。
-
helper.setFrom(mailProperties.getUsername());
这里从哪发送我为什么要这么写呢?这是出于灵活变化的考虑,如果在这里写死的话,那么每次变化发送人的时候,我要在配置文件和代码里改两次。所以我的发送人,就写从配置文件里传来的人。
首先到配置文件的spring.mail.username,按住Ctrl,你会发现配置文件也是把这些信息注入到了MailProperties;
所以我把这个类注入进来,直接获取username,这样配置文件更改的时候,我的代码就不必更改了; -
渲染邮件模板
注入TemplateEngine,它属于org.thymeleaf.包下面。
实现他下面的process方法,点击源码看:
他需要一个模板名,我们这边要被渲染的模板叫mail,还需要一个context,那么我们就new一个Context给他。
然后逐一对应的写变量和要传入的参数。 -
最后设置setText,点击源码:
首先他需要一个发送的文本,我们把
String mail = templateEngine.process("mail", context);
赋值给一个参数,传进去,然后第二个参数问你是不是HTML,传入true;
- 把传入的邮件发送出去
javaMailSender.send(mimeMessage);
说明
传入的数据如果是通过数据库来动态获取的话,需要在对应的实体类上实现序列化接口。
OK,通过队列实现邮件发送就说到这里;
也许有人看到这里还在想,用队列到底有什么作用啊?没看出来啊!这里我说一下,假如你从前端传入完参数运行出了点问题,但是中间件这边收到了邮件。那么在下次请求完成之后,他会自动的把之前的保存在中间件的邮件发送过去!
详细请参考
https://mp.weixin.qq.com/s/fKAjWkbzM0X9MLHVaPUEHQ
公众号也可以关注:江南一点雨,有很多的学习资源和视频;
哔哩哔哩上可以搜狂神说,里面有很多入门级视频教程;