SpringBoot整合郵件發(fā)送的四種方法
前言
郵件發(fā)送,聽著很神秘,然而對于Spring Boot來說,這個功能已被集成好,只需引入spring-boot-starter-mail依賴后,少量代碼即可實(shí)現(xiàn)大部分郵件發(fā)送需求。
因發(fā)送郵件的方法只是在調(diào)用上,略有改動(比如,設(shè)置參數(shù)是否包含有ture),故在代碼編排上,寫在一個類中了,后面單元測試時分開測試即可。
¥¥¥¥¥具體操作步驟如下¥¥¥¥¥
一、創(chuàng)建Spring boot工程后,在pom.xml中添加依賴
1.1、方式一,新建工程時,在IO選項(xiàng)勾選郵件依賴

勾選后,spring-boot-starter-mail 依賴會被自動引入到pom.xml中
1.2、方式二,手動在pom.xml中添加依賴
引入:mail核心依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>其他相關(guān)依賴,可以酌情引入,需要注意的是,如果在項(xiàng)目中,無法自動導(dǎo)入依賴包,則很可能是下面的某個依賴,你沒有引入,引入后鼠標(biāo)右鍵pom.xml-->Maven-->Reload Project,就可以了。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <!--不使用默認(rèn)的 logback日志,使用下面的log4j2--> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- 移除掉默認(rèn)支持的 Tomcat --> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!-- 添加 Undertow 容器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- aop 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- 用于日志切面中,以 gson 格式打印出入?yún)?--> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency> <!-- 引入DevTools熱部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency>
二、在工程resource目錄下創(chuàng)建application.properties文件,并添加相關(guān)配置
注意:下面的郵箱地址,是你自己的郵箱(作為郵件的發(fā)送者);密碼是對應(yīng)郵箱的登錄密碼或授權(quán)碼,授權(quán)碼在下方會有詳細(xì)介紹,本文以163郵箱為例!
# 發(fā)送郵件的服務(wù)器, # QQ 郵件:smtp.qq.com # 如果是163郵箱,變更為“smtp.163.com”即可 spring.mail.host=smtp.163.com #你的郵箱地址 spring.mail.username=123456789@163.com #授權(quán)碼,或郵箱登錄密碼 spring.mail.password=123456 #是否開啟驗(yàn)證 true為開啟,false不開啟 spring.mail.properties.mail.smtp.auth=true #通訊是否加密,true開啟,false不開啟 spring.mail.properties.mail.smtp.starttls.enable=true #是否必須通過使用加密通訊進(jìn)行通訊,true開啟,false不開啟 spring.mail.properties.mail.smtp.starttls.required=true
提示:如果你想使用application.yml配置文件,則格式如下
spring:
mail:
host: smtp.qq.com #發(fā)送郵件的服務(wù)器
username: 你的郵箱地址
password: 授權(quán)碼,或郵箱密碼
properties.mail.smtp.auth: true
properties.mail.smtp.starttls.enable: true
default-encoding: utf-8三、關(guān)于授權(quán)碼
如果使用的是 163 郵箱,或者 Gmail 郵箱,直接使用密碼就可以了,如果使用的是 QQ 郵箱,則需要先獲取授權(quán)碼。
3.1、什么是 QQ 郵箱授權(quán)碼
官方解釋如下圖所示

3.2、如何獲取QQ授權(quán)碼
3.2.1、登錄 QQ 郵箱

3.2.2、點(diǎn)擊設(shè)置,再點(diǎn)擊頁簽中的“賬戶”

3.2.3、跳轉(zhuǎn)頁面后,點(diǎn)擊賬戶,將頁面往下拖動,您會看到,授權(quán)碼的開啟菜單

3.2.4、點(diǎn)擊“開啟”,驗(yàn)證成功過后,即可獲取授權(quán)碼

3.3、163郵箱的授權(quán)碼
我的賬號默認(rèn)是開啟的,如果你的沒有開啟,如下步驟操作
3.3.1、點(diǎn)擊頂部頁簽的”"設(shè)置"按鈕,進(jìn)入POP3設(shè)置界面

3.3.2、開啟服務(wù),也可以重新生成授權(quán)碼

3.4、 發(fā)送郵件所需要遵從的POP3/SMTP/IMAP三個協(xié)議的簡述
SMTP(Simple Mail Transfer Protocol):簡單郵件傳輸協(xié)議,用于發(fā)送電子郵件的傳輸協(xié)議。
POP3(Post Office Protocol - Version 3):用于接收電子郵件的標(biāo)準(zhǔn)協(xié)議。
IMAP(Internet Mail Access Protocol):互聯(lián)網(wǎng)消息協(xié)議,是POP3的替代協(xié)議。
簡而言之,SMTP是發(fā)郵件必須遵從的標(biāo)準(zhǔn),POP3是接收郵件要遵從的標(biāo)準(zhǔn),而IMAP是對POP3協(xié)議的升級,日常工作中,我們主要使用的是發(fā)郵件操作。
四、業(yè)務(wù)代碼
4.1、新增MailService接口,并聲明4個發(fā)送不同類型郵件的方法
注:入?yún)⒍嘤?個的情況下,通常也會把入?yún)⒎庋b為一個實(shí)體Bean,方便起見,這里就不封裝了。
package com.example.demo.service;
/**
* @author xyp
* @create 2022-10-07 12:57
* @describe 郵件發(fā)送接口,定義發(fā)送不同類型郵件的方法
*/
public interface MailService {
/**
* 發(fā)送簡單文本的郵件
* @param to
* @param subject
* @param content
* @return
*/
boolean sendSimpleText(String to, String subject, String content);
/**
* 發(fā)送 html 的郵件
* @param to
* @param subject
* @param html
* @return
*/
boolean sendWithHtml(String to, String subject, String html);
/**
* 發(fā)送帶有圖片的 html 的郵件
* @param to
* @param subject
* @param html
* @param cids
* @param filePaths
* @return
*/
boolean sendWithImageHtml(String to, String subject, String html, String[] cids, String[] filePaths);
/**
* 發(fā)送帶有附件的郵件
* @param to
* @param subject
* @param content
* @param filePaths
* @return
*/
boolean sendWithWithEnclosure(String to, String subject, String content, String[] filePaths);
}
4.2、新增MailService接口的實(shí)現(xiàn)類MailServiceImpl
package com.example.demo.service.impl;
import com.example.demo.service.MailService;
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 javax.mail.internet.MimeMessage;
/**
* @author xyp
* @create 2022-10-07 13:01
* @describe
*/
@Component //沒有這個注解,發(fā)送郵件時可能會引發(fā)空指針異常
public class MailServiceImpl implements MailService {
private final static Logger logger = LoggerFactory.getLogger(MailServiceImpl.class);
@Autowired
private MailProperties mailProperties;
@Autowired
private JavaMailSender javaMailSender;
@Override
public boolean sendSimpleText(String to, String subject, String content) {
logger.info("## Ready to send mail ...");
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
// 郵件發(fā)送來源
simpleMailMessage.setFrom(mailProperties.getUsername());
// 郵件發(fā)送目標(biāo)
simpleMailMessage.setTo(to);
// 設(shè)置標(biāo)題
simpleMailMessage.setSubject(subject);
// 設(shè)置內(nèi)容
simpleMailMessage.setText(content);
try {
// 發(fā)送
javaMailSender.send(simpleMailMessage);
logger.info("## Send the mail success ...");
} catch (Exception e) {
logger.error("Send mail error: ", e);
return false;
}
return true;
}
@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);
// 郵件發(fā)送來源
mimeMessageHelper.setFrom(mailProperties.getUsername());
// 郵件發(fā)送目標(biāo)
mimeMessageHelper.setTo(to);
// 設(shè)置標(biāo)題
mimeMessageHelper.setSubject(subject);
// 設(shè)置內(nèi)容,并設(shè)置內(nèi)容 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;
}
@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);
// 郵件發(fā)送來源
mimeMessageHelper.setFrom(mailProperties.getUsername());
// 郵件發(fā)送目標(biāo)
mimeMessageHelper.setTo(to);
// 設(shè)置標(biāo)題
mimeMessageHelper.setSubject(subject);
// 設(shè)置內(nèi)容,并設(shè)置內(nèi)容 html 格式為 true
mimeMessageHelper.setText(html, true);
// 設(shè)置 html 中內(nèi)聯(lián)的圖片
for (int i = 0; i < cids.length; i++) {
FileSystemResource file = new FileSystemResource(filePaths[i]);
// addInline() 方法 cid 需要 html 中的 cid (Content ID) 對應(yīng),才能設(shè)置圖片成功,
// 具體可以參見,下面 4.3.3 單元測試的參數(shù)設(shè)置
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;
}
@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 {
// 設(shè)置為true,代表要支持附件
mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
// 郵件發(fā)送來源
mimeMessageHelper.setFrom(mailProperties.getUsername());
// 郵件發(fā)送目標(biāo)
mimeMessageHelper.setTo(to);
// 設(shè)置標(biāo)題
mimeMessageHelper.setSubject(subject);
// 設(shè)置內(nèi)容
mimeMessageHelper.setText(content);
// 添加附件
for (int i = 0; i < filePaths.length; i++) {
FileSystemResource file = new FileSystemResource(filePaths[i]);
String attachementFileName = "附件" + (i + 1)+"_"+ file.getFilename();
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.3、工程目錄結(jié)構(gòu)查看
如下圖所示,核心的幾個類,都被紅色的框,框選著的,其他一些package與本項(xiàng)目無關(guān)。

五、單元測試,查看成果
準(zhǔn)備工作
1、在pom中引入單元測試的依賴
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> <scope>test</scope> </dependency>
需要注意的是,在單元測試類中,所有與單元測試類相關(guān)的類,都來自于junit,不要使用默認(rèn)的。
2、在test單元測試目錄,新建SpringBootMailTest.java類

5.1、發(fā)送純文本郵件的測試
5.1.1、測試代碼編寫
package com.example.demo;
import com.example.demo.service.MailService;
import org.junit.Assert;//注意這個包是junit的,不是自帶的
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author xyp
* @create 2022-10-07 15:07
* @describe
*/
@SpringBootTest
public class SpringBootMailTest {
@Autowired(required = false)
private MailService mailService;
@Test
public void sendSimpleText(){
String to="871038951@qq.com";
String title="標(biāo)題:簡單的文本發(fā)送測試";
String content="簡單的文本";
Assert.assertTrue(mailService.sendSimpleText(to,title,content));
}
}
5.1.2、運(yùn)行查看,報錯小插曲

初次運(yùn)行,可能會報如下錯誤

經(jīng)百般百度后,得知需要給MailServicel的實(shí)現(xiàn)類MailServiceImpl添加@Component注解

5.1.3、給MailServiceImpl添加@Component注解后,再試



至此,第一個純文本郵件發(fā)送,測試成功!
5.2、發(fā)送純HTML文本測試
5.2.1、測試代碼編寫
@Test
public void sendHtml(){
String to="871038951@qq.com";
String title="標(biāo)題:Html文本發(fā)送測試";
String htmlContent="<html><body><h1>歡迎來到 Spring boot 的世界</h1></body></html>";
Assert.assertTrue(mailService.sendWithHtml(to,title,htmlContent));
}5.2.2、運(yùn)行并查看結(jié)果

運(yùn)行后,收到郵件提示

進(jìn)入郵箱,并打開


至此,第二個發(fā)送Html的測試,測試成功!
5.3、發(fā)送帶圖片的HTML測試
5.3.1、測試代碼編寫
@Test
public void sendWithImageHtml(){
String to="871038951@qq.com";
String title="標(biāo)題:帶有圖片的Html發(fā)送測試";
String htmlContent="<html><body>" +
"<h1>歡迎來到 Spring boot 的世界</h1>" +
"<image width='50' height='60' src='cid:test1'>圖片1 </image>" +//cid:是約定好的固定格式,只需要修改后面的變量
"<image width='50' height='60' src='cid:test2'>圖片1 </image>" +
"</body></html>";
//數(shù)組中的cid要和上面html中image中的cid一致,否則圖片將設(shè)置失敗
String[] cids=new String[]{"test1","test2"};
String[] filePaths=new String[]{
"D:\\Documents\\ioc\\MyIco\\pao1.ico",
"D:\\Documents\\ioc\\MyIco\\xiang2.ico"
};
Assertions.assertTrue(mailService.sendWithImageHtml(to,title,htmlContent,cids,filePaths));
}5.3.2、運(yùn)行并查看結(jié)果

電腦右下角有郵件提醒

進(jìn)入郵箱,查看郵件


至此,第三個發(fā)送帶圖片的Html郵件,測試成功!
5.4、發(fā)送帶附件的測試
5.4.1、測試代碼編寫
@Test
public void sendWithWithEnclosure(){
String to="871038951@qq.com";
String title="標(biāo)題:帶有附件的郵件發(fā)送測試";
String content="歡迎來到 Spring boot 的世界";
String[] filePaths=new String[]{
"D:\\Documents\\ioc\\MyIco\\pao1.ico",
"D:\\Documents\\ioc\\MyIco\\expect5.45.tar.gz"
};
Assert.assertTrue(mailService.sendWithWithEnclosure(to,title,content,filePaths));
}5.5.2、運(yùn)行并查看結(jié)果

注:剛開始附件,測試的是圖片,為了測試壓縮包是否能被當(dāng)做附件發(fā)送,又新增了壓縮包的測試。
電腦右下角彈出新郵件提示:

進(jìn)入收件箱查看郵件


經(jīng)測試,下載后,附件可以正常打開。
至此,各個案例都演示完畢!
案例雖然簡單,總的來說,這個幾個方法還是有一定的局限性,不過它為我們今后整合一個功能更齊全的郵件發(fā)送功能,帶來的指引和啟發(fā),已經(jīng)夠用了。
注意下面幾行點(diǎn)參數(shù)中true的含義:
//純文本郵件,不用帶任何參數(shù) SimpleMailMessage simpleMailMessage = new SimpleMailMessage(); simpleMailMessage .setText(contentText);
// 郵件內(nèi)容如果是html和圖片,則下面兩處都需要設(shè)置為true mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);//如果是僅支持附件,這一處設(shè)置為true即可 mimeMessageHelper.setText(html, true);
注意:連續(xù)發(fā)內(nèi)容相同的郵件,會被判定為垃圾郵件,可能會被攔截。
到此這篇關(guān)于SpringBoot整合郵件發(fā)送的四種方法的文章就介紹到這了,更多相關(guān)SpringBoot郵件發(fā)送內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 使用SpringBoot發(fā)送郵件的方法詳解
- SpringBoot實(shí)現(xiàn)定時發(fā)送郵件的三種方法案例詳解
- Springboot發(fā)送郵件功能的實(shí)現(xiàn)詳解
- SpringBoot實(shí)現(xiàn)發(fā)送QQ郵件的示例代碼
- SpringBoot?Mail郵件任務(wù)詳情
- SpringBoot?集成短信和郵件的配置示例詳解
- SpringBoot實(shí)現(xiàn)郵件發(fā)送的示例代碼
- SpringBoot實(shí)現(xiàn)發(fā)送郵件、發(fā)送微信公眾號推送功能
- Spring?Boot整合郵箱發(fā)送郵件實(shí)例
- SpringBoot實(shí)現(xiàn)發(fā)送電子郵件
- SpringBoot整合JavaMail實(shí)現(xiàn)發(fā)郵件的項(xiàng)目實(shí)踐
相關(guān)文章
Java?DirectByteBuffer堆外內(nèi)存回收詳解
這篇文章主要為大家詳細(xì)介紹了Java中發(fā)DirectByteBuffer堆外內(nèi)存回收,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,需要的可以參考一下2022-10-10
java實(shí)現(xiàn)優(yōu)酷視頻地址解析示例代碼分享
最近做了一個在線視頻的下載器,需要解析youku的視頻,獲得真正的視頻地址,現(xiàn)在把解析過程記錄下來以供參考2014-01-01
java枚舉enum,根據(jù)value值獲取key鍵的操作
這篇文章主要介紹了java枚舉enum,根據(jù)value值獲取key鍵的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
Java中三種零拷貝的實(shí)現(xiàn)示例以及對比詳解
這篇文章主要介紹了Java中三種零拷貝的實(shí)現(xiàn)示例以及對比詳解,本文主要是介紹幾種零拷貝的實(shí)現(xiàn)示例,以及與最傳統(tǒng)的做一個對比,看看在效率上到底有多大的提升,需要的朋友可以參考下2023-12-12
總結(jié)一下Java回調(diào)機(jī)制的相關(guān)知識
今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著Java回調(diào)機(jī)制展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06

