文章首發自個人微信公眾號: 小哈學Java
大家好,後續會間斷地奉上一些 Spring Boot 2.x 相關的博文,包括 Spring Boot 2.x 教程和 Spring Boot 2.x 新特性教程相關,如 WebFlux 等。還有自定義 Starter 元件的進階教程,比如:如何手擼一個自定義圖床 Starter 啟動器(支援上傳到伺服器內部,阿里 OSS 和七牛雲等), 僅僅需要配置相關引數,就可以將圖片上傳功能整合到現有的專案中。
好吧,這些都是後話。今天主要來講講如何在 Spring Boot 2.x 版本中整合傳送郵件功能。
可以說,郵件傳送在企業級應用中是比較常見的服務了,如運維報警,使用者啟用,廣告推廣等場景,均會使用到它。廢話少說,開幹!
目錄
一、新增依賴
二、新增郵件相關配置
三、關於授權碼
- 3.1 什麼是 QQ 郵箱授權碼
- 3.2 如何獲取
四、開始編碼
- 4.1 定義功能類
- 4.2 專案結構
- 4.3 單元測試,驗證效果
五、總結
六、GitHub 原始碼地址
一、新增依賴
在 pom.xml
檔案中新增 spring-boot-starter-mail
依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
複製程式碼
二、新增郵件相關配置
在 application.properties
配置檔案中新增下面內容:
# 傳送郵件的伺服器,筆者這裡使用的 QQ 郵件
spring.mail.host=smtp.qq.com
spring.mail.username=你的郵箱地址
spring.mail.password=授權碼,或郵箱密碼
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
複製程式碼
yml
格式的配置檔案,新增如下:
spring:
mail:
host: smtp.qq.com #傳送郵件的伺服器,筆者這裡使用的 QQ 郵件
username: 你的郵箱地址
password: 授權碼,或郵箱密碼
properties.mail.smtp.auth: true
properties.mail.smtp.starttls.enable: true
default-encoding: utf-8
複製程式碼
三、關於授權碼
對於上面的配置,您肯定對密碼配置那塊還抱有疑問,如果您使用的是 163 郵箱,或者 Gmail 郵箱,直接使用密碼就可以了,如果您使用的是 QQ 郵箱,則需要先獲取授權碼。
到底什麼事授權碼? :
3.1 什麼是 QQ 郵箱授權碼
下圖截自 QQ 郵箱官方文件:
3.2 如何獲取
登入 QQ 郵箱:
點選設定:
跳轉頁面後,點選賬戶,將頁面往下拖動,您會看到:
驗證成功過後,即可獲取授權碼:
四、開始編碼
4.1 定義功能類
先定義一個郵件服務的介面類, MailService.java
:
package site.exception.springbootmail.service;
/**
* @author 犬小哈(微訊號: 小哈學Java)
* @site 個人網站: www.exception.site
* @date 2019/4/10
* @time 下午4:19
* @discription
**/
public interface MailService {
/**
* 傳送簡單文字的郵件
* @param to
* @param subject
* @param content
* @return
*/
boolean send(String to, String subject, String content);
/**
* 傳送 html 的郵件
* @param to
* @param subject
* @param html
* @return
*/
boolean sendWithHtml(String to, String subject, String html);
/**
* 傳送帶有圖片的 html 的郵件
* @param to
* @param subject
* @param html
* @param cids
* @param filePaths
* @return
*/
boolean sendWithImageHtml(String to, String subject, String html, String[] cids, String[] filePaths);
/**
* 傳送帶有附件的郵件
* @param to
* @param subject
* @param content
* @param filePaths
* @return
*/
boolean sendWithWithEnclosure(String to, String subject, String content, String[] filePaths);
}
複製程式碼
介面內定義了四個方法:
send()
: 傳送簡單文字的郵件;sendWithHtml()
: 傳送 html 的郵件;sendWithImageHtml()
: 傳送帶有圖片的 html 的郵件;sendWithWithEnclosure
: 傳送帶有附件的郵件;
完成介面的定義以後,我們再定義一個具體實現類,MailServiceImpl.java
:
package site.exception.springbootmail.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mail.MailProperties;
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 org.springframework.util.Assert;
import site.exception.springbootmail.service.MailService;
import javax.mail.internet.MimeMessage;
/**
* @author 犬小哈(微訊號: 小哈學Java)
* @site 個人網站: www.exception.site
* @date 2019/4/10
* @time 下午4:19
* @discription
**/
@Service
public class MailServiceImpl implements MailService {
private final static Logger logger = LoggerFactory.getLogger(MailServiceImpl.class);
@Autowired
private MailProperties mailProperties;
@Autowired
private JavaMailSender javaMailSender;
/**
* 傳送簡單文字的郵件
* @param to
* @param subject
* @param content
* @return
*/
@Override
public boolean send(String to, String subject, String content) {
logger.info("## Ready to send mail ...");
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
// 郵件傳送來源
simpleMailMessage.setFrom(mailProperties.getUsername());
// 郵件傳送目標
simpleMailMessage.setTo(to);
// 設定標題
simpleMailMessage.setSubject(subject);
// 設定內容
simpleMailMessage.setText(content);
try {
// 傳送
javaMailSender.send(simpleMailMessage);
logger.info("## Send the mail success ...");
} catch (Exception e) {
logger.error("Send mail error: ", e);
return false;
}
return true;
}
/**
* 傳送 html 的郵件
* @param to
* @param subject
* @param html
* @return
*/
@Override
public boolean sendWithHtml(String to, String subject, String html) {
logger.info("## Ready to send mail ...");
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = null;
try {
mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
// 郵件傳送來源
mimeMessageHelper.setFrom(mailProperties.getUsername());
// 郵件傳送目標
mimeMessageHelper.setTo(to);
// 設定標題
mimeMessageHelper.setSubject(subject);
// 設定內容,並設定內容 html 格式為 true
mimeMessageHelper.setText(html, true);
javaMailSender.send(mimeMessage);
logger.info("## Send the mail with html success ...");
} catch (Exception e) {
e.printStackTrace();
logger.error("Send html mail error: ", e);
return false;
}
return true;
}
/**
* 傳送帶有圖片的 html 的郵件
* @param to
* @param subject
* @param html
* @param cids
* @param filePaths
* @return
*/
@Override
public boolean sendWithImageHtml(String to, String subject, String html, String[] cids, String[] filePaths) {
logger.info("## Ready to send mail ...");
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = null;
try {
mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
// 郵件傳送來源
mimeMessageHelper.setFrom(mailProperties.getUsername());
// 郵件傳送目標
mimeMessageHelper.setTo(to);
// 設定標題
mimeMessageHelper.setSubject(subject);
// 設定內容,並設定內容 html 格式為 true
mimeMessageHelper.setText(html, true);
// 設定 html 中內聯的圖片
for (int i = 0; i < cids.length; i++) {
FileSystemResource file = new FileSystemResource(filePaths[i]);
// addInline() 方法 cid 需要 html 中的 cid (Content ID) 對應,才能設定圖片成功,
// 具體可以參見,下面 4.3.3 單元測試的引數設定
mimeMessageHelper.addInline(cids[i], file);
}
javaMailSender.send(mimeMessage);
logger.info("## Send the mail with image success ...");
} catch (Exception e) {
e.printStackTrace();
logger.error("Send html mail error: ", e);
return false;
}
return true;
}
/**
* 傳送帶有附件的郵件
* @param to
* @param subject
* @param content
* @param filePaths
* @return
*/
@Override
public boolean sendWithWithEnclosure(String to, String subject, String content, String[] filePaths) {
logger.info("## Ready to send mail ...");
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = null;
try {
mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
// 郵件傳送來源
mimeMessageHelper.setFrom(mailProperties.getUsername());
// 郵件傳送目標
mimeMessageHelper.setTo(to);
// 設定標題
mimeMessageHelper.setSubject(subject);
// 設定內容
mimeMessageHelper.setText(content);
// 新增附件
for (int i = 0; i < filePaths.length; i++) {
FileSystemResource file = new FileSystemResource(filePaths[i]);
String attachementFileName = "附件" + (i + 1);
mimeMessageHelper.addAttachment(attachementFileName, file);
}
javaMailSender.send(mimeMessage);
logger.info("## Send the mail with enclosure success ...");
} catch (Exception e) {
logger.error("Send html mail error: ", e);
return false;
}
return true;
}
}
複製程式碼
4.2 專案結構
完成上面功能類的編碼後,看下專案結構如下:
4.3 單元測試,驗證效果
4.3.1 簡單文字傳送
填寫相關測試引數,包括目標郵箱地址,標題,內容,執行單元測試:
單元測試通過,再看下實際效果:
郵件正常傳送。
4.3.2 傳送 Html
填寫相關測試引數,包括目標郵箱地址,標題,html 內容,執行單元測試通過,直接看效果:
可以看到,郵件傳送成功!
4.3.3 傳送帶有圖片的 Html
填寫相關測試引數,包括目標郵箱地址,標題,html 內容,html 中包含了兩張圖片,並且 src
中的內容是 cid:{flag}
的格式,字首 cid:
是固定的,您需要改變是後面的標誌位,通過 addInline(cid, file)
來將 cid
和具體的圖片檔案對應起來。
執行單元測試通過,看看效果如何:
可以看到 html 中圖片也是 OK 的。
PS: 這裡筆者在測試傳送給 QQ 郵箱的時候,圖片顯示不成功,暫時還沒找到問題在哪,如果有哪位讀者知道,不妨後臺發個訊息告訴一下筆者哈。
4.3.4 傳送帶有附件的郵件
填寫相關測試引數,包括目標郵箱地址,標題,內容,並新增了兩個附件,執行單元測試,看看實際效果:傳送成功,到此所有的單元測試全部執行通過。
五、總結
本文中,我們學習如何在 Spring Boot 2.x 版本中整合傳送郵件功能,包括髮送簡單文字,Html 內容,帶有圖片的 Html 內容,以及帶有的附加的郵件,希望對您有所幫助!