準備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
公衆號也可以關注:江南一點雨,有很多的學習資源和視頻;
嗶哩嗶哩上可以搜狂神說,裏面有很多入門級視頻教程;