目錄html
從1969年10月世界上的第一封電子郵件發出,到2019年,已通過去將近半個世紀了。雖然即時通信和視頻會議,甚至全息投影都變得日益普及,但電子郵件依然有着普遍的使用場景和不可撼動的歷史地位。java
SpringBoot擁有強大的生態鏈,幾乎能夠鏈接全部主流的開源庫。git
下面咱們就從電子郵件發送的歷史再到原理,而後如何本身配置郵件服務器併發送郵件,一步步講解。github
本文實現源碼能夠在這裏找到: SpringBoot發送電子郵件源碼web
1969年10月世界上的第一封電子郵件是由計算機科學家Leonard K.教授發給他的同事的一條簡短消息。第一條網上信息就是‘LO’,意思是‘你好!’。spring
在此以後,1987年9月14日中國的第一封電子郵件,這封郵件是由德國維爾納·措恩與中國的王運豐在北京計算機應用技術研究所,發往德國一個大學的,郵件內容頗具深意,「Across the Great Wall we can reach every corner in the world.(越過長城,走向世界)」,這是中國經過北京與德國大學之間的網絡鏈接,向全球科學網發出的第一封電子郵件。瀏覽器
接下來中國的電子郵件進入了30年的發展期,雖然在1987年就有了電子郵件,可是,真正的郵件興起,應該在90年代到2000年之間,由於在1987的時候中國網速特別慢,真正能接觸到互聯網的用戶是很是少的,到了90年代中期,互聯網瀏覽器的誕生,使得全民上網人數激增,電子郵件被普遍使用,此時,中國的部分學生在研究中使用到電子郵件,真正普及的時間是在2000年左右。安全
Java在發明之初,就開始支持發送郵件,經過java mail包方式去操做郵件發送的內容和協議,可是,這種發送方式稍微比較複雜,須要配置各類參數、協議、內容,以後產生了Spring框架。springboot
Spring在java mail的基礎上進行了一些封裝,使發送郵件的過程的複雜大大減小。服務器
SpringBoot Mail在Spring Mail的基礎上,再次進行一次封裝,使得發送郵件的便利度上,更爲簡單。
用戶要在Internet上提供電子郵件功能,必須有專門的電子郵件服務器。這些郵件服務器就相似於現實生活中的郵局,它主要負責接收用戶投遞過來的郵件,並把郵件投遞到郵件接收者的電子郵箱中。
郵件服務器就好像是互聯網世界的郵局。按照功能劃分,郵件服務器能夠劃分爲兩種類型:
電子郵箱也稱爲E-mail地址,用戶能夠經過E-mail地址來標識本身發送的電子郵件,也能夠經過這個地址接收別人發來的電子郵件。電子郵箱須要到郵件服務器進行申請,也就是說,電子郵箱其實就是用戶在郵件服務器上申請的帳戶。郵件服務器會把接收到的郵件保存到爲該帳戶所分配的郵箱空間中,用戶經過用戶名密碼登陸到郵件服務器查收該地址已經收到的郵件。通常來說,郵件服務器爲用戶分配的郵箱空間是有限的。
咱們能夠直接在網站上進行郵件收發,也可使用常見的FoxMail、Outlook等郵件客戶端軟件接受郵件。郵件客戶端軟件一般集郵件撰寫、發送和收發功能於一體,主要用於幫助用戶將郵件發送給SMTP郵件服務器和從POP3/IMAP郵件服務器讀取用戶的電子郵件。
電子郵件須要在郵件客戶端和郵件服務器之間,以及兩個郵件服務器之間進行郵件傳遞,那就必需要遵照必定的規則,這個規則就是郵件傳輸協議。下面咱們分別簡單介紹幾種協議:
要想各類郵件處理程序能識別咱們所寫的電子郵件,能從咱們所書寫的電子郵件中分析和提取出發件人、收件人、郵件主題和郵件內容以及附件等信息,那麼咱們所寫的電子郵件必需要遵循必定的格式要求,而這種郵件內容的基本格式和具體細節分別是由 RFC822 文檔和 MIME 協議定義的。
圖示的六個步驟分別進行以下的說明:
①用戶A的電子郵箱爲:xx@qq.com,經過郵件客戶端軟件寫好一封郵件,交到QQ的郵件服務器,這一步使用的協議是SMTP,對應圖示的①;
②QQ郵箱會根據用戶A發送的郵件進行解析,也就是根據收件地址判斷是不是本身管轄的帳戶,若是收件地址也是QQ郵箱,那麼會直接存放到本身的存儲空間。這裏咱們假設收件地址不是QQ郵箱,而是163郵箱,那麼QQ郵箱就會將郵件轉發到163郵箱服務器,轉發使用的協議也是SMTP,對應圖示的②;
③163郵箱服務器接收到QQ郵箱轉發過來的郵件,也會判斷收件地址是不是本身,發現是本身的帳戶,那麼就會將QQ郵箱轉發過來的郵件存放到本身的內部存儲空間,對應圖示的③;
④用戶A將郵件發送了以後,就會通知用戶B去指定的郵箱收取郵件。用戶B會經過郵件客戶端軟件先向163郵箱服務器請求,要求收取本身的郵件,對應圖示的④;
⑤163郵箱服務器收到用戶B的請求後,會從本身的存儲空間中取出B未收取的郵件,對應圖示⑤;
⑥163郵箱服務器取出用戶B未收取的郵件後,將郵件發給用戶B,對應圖示的⑥;最後三步用戶B收取郵件的過程,使用的協議是POP3;
在系統中電子郵件的使用場景:
註冊驗證
營銷推送
觸發機制
監控報警
電子郵件是業務和安全的最後一道防線 —— 當系統沒法自動處理的時候,經過郵件提醒相關支持人員。
註冊發件郵箱並設置客戶端受權碼,這裏以163免費郵箱爲例:
搭建完項目之後,進行下面的兩步配置。
application.properties配置參數:
# 郵箱配置
spring.mail.host=smtp.163.com
# 你的163郵箱
spring.mail.username=ispringboot@163.com
# 注意這裏不是郵箱密碼,而是SMTP受權密碼
spring.mail.password=isb001
spring.mail.port=25
spring.mail.protocol=smtp
spring.mail.default-encoding=UTF-8
複製代碼
pom.xml依賴spring-boot-starter-mail模塊:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
複製代碼
MailService.java:
package org.ijiangtao.tech.spring.boot.mail.imail.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
@Service
public class MailService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${spring.mail.username}")
private String from;
@Autowired
private JavaMailSender mailSender;
/** * 簡單文本郵件 * @param to 接收者郵件 * @param subject 郵件主題 * @param contnet 郵件內容 */
public void sendSimpleMail(String to, String subject, String contnet){
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setText(contnet);
message.setFrom(from);
mailSender.send(message);
}
/** * HTML 文本郵件 * @param to 接收者郵件 * @param subject 郵件主題 * @param contnet HTML內容 * @throws MessagingException */
public void sendHtmlMail(String to, String subject, String contnet) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(contnet, true);
helper.setFrom(from);
mailSender.send(message);
}
/** * 附件郵件 * @param to 接收者郵件 * @param subject 郵件主題 * @param contnet HTML內容 * @param filePath 附件路徑 * @throws MessagingException */
public void sendAttachmentsMail(String to, String subject, String contnet, String filePath) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(contnet, true);
helper.setFrom(from);
FileSystemResource file = new FileSystemResource(new File(filePath));
String fileName = file.getFilename();
helper.addAttachment(fileName, file);
mailSender.send(message);
}
/** * 圖片郵件 * @param to 接收者郵件 * @param subject 郵件主題 * @param contnet HTML內容 * @param rscPath 圖片路徑 * @param rscId 圖片ID * @throws MessagingException */
public void sendInlinkResourceMail(String to, String subject, String contnet, String rscPath, String rscId) {
logger.info("發送靜態郵件開始: {},{},{},{},{}", to, subject, contnet, rscPath, rscId);
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = null;
try {
helper = new MimeMessageHelper(message, true);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(contnet, true);
helper.setFrom(from);
FileSystemResource res = new FileSystemResource(new File(rscPath));
helper.addInline(rscId, res);
mailSender.send(message);
logger.info("發送靜態郵件成功!");
} catch (MessagingException e) {
logger.info("發送靜態郵件失敗: ", e);
}
}
}
複製代碼
咱們使用thymeleaf做爲模板引擎。
emailTeplate.html:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>註冊-測試郵件模板</title>
</head>
<body>
你好,感謝你的註冊,這是一封驗證郵件,請點擊下面的鏈接完成註冊,感謝您的支持。
<a href="#" th:href="@{https://github.com/{id}(id=${id})}">激活帳戶</a>
</body>
</html>
複製代碼
測試發送郵件,使用單元測試MailServiceTest.java:
package org.ijiangtao.tech.spring.boot.mail.imail.service;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.annotation.Resource;
import javax.mail.MessagingException;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MailServiceTest {
@Autowired
private MailService mailService;
@Resource
private TemplateEngine templateEngine;
@Test
public void sendSimpleMail() {
mailService.sendSimpleMail("ispringboot@163.com","測試spring boot imail-主題","測試spring boot imail - 內容");
}
@Test
public void sendHtmlMail() throws MessagingException {
String content = "<html>\n" +
"<body>\n" +
"<h3>hello world</h3>\n" +
"<h1>html</h1>\n" +
"<body>\n" +
"</html>\n";
mailService.sendHtmlMail("ispringboot@163.com","這是一封HTML郵件",content);
}
@Test
public void sendAttachmentsMail() throws MessagingException {
String filePath = "/ijiangtao/軟件開發前景.docx";
String content = "<html>\n" +
"<body>\n" +
"<h3>hello world</h3>\n" +
"<h1>html</h1>\n" +
"<h1>附件傳輸</h1>\n" +
"<body>\n" +
"</html>\n";
mailService.sendAttachmentsMail("ispringboot@163.com","這是一封HTML郵件",content, filePath);
}
@Test
public void sendInlinkResourceMail() throws MessagingException {
//TODO 改成本地圖片目錄
String imgPath = "/ijiangtao/img/blob/dd9899b4cf95cbf074ddc4607007046c022564cb/blog/animal/dog/dog-at-work-with-computer-2.jpg?raw=true";
String rscId = "admxj001";
String content = "<html>" +
"<body>" +
"<h3>hello world</h3>" +
"<h1>html</h1>" +
"<h1>圖片郵件</h1>" +
"<img src='cid:"+rscId+"'></img>" +
"<body>" +
"</html>";
mailService.sendInlinkResourceMail("ispringboot@163.com","這是一封圖片郵件",content, imgPath, rscId);
}
@Test
public void testTemplateMailTest() throws MessagingException {
Context context = new Context();
context.setVariable("id","ispringboot");
String emailContent = templateEngine.process("emailTeplate", context);
mailService.sendHtmlMail("ispringboot@163.com","這是一封HTML模板郵件",emailContent);
}
}
複製代碼
測試結果,收到了電子郵件:
在生產環境,通常郵件服務會單獨部署,並經過HTTP或MQ等方式暴露出來。