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

勾選后,spring-boot-starter-mail 依賴會(huì)被自動(dòng)引入到pom.xml中
1.2、方式二,手動(dòng)在pom.xml中添加依賴
引入:mail核心依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>其他相關(guān)依賴,可以酌情引入,需要注意的是,如果在項(xiàng)目中,無法自動(dòng)導(dǎo)入依賴包,則很可能是下面的某個(gè)依賴,你沒有引入,引入后鼠標(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ā)送者);密碼是對(duì)應(yīng)郵箱的登錄密碼或授權(quán)碼,授權(quán)碼在下方會(huì)有詳細(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)擊賬戶,將頁面往下拖動(dòng),您會(huì)看到,授權(quán)碼的開啟菜單

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

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

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

3.4、 發(fā)送郵件所需要遵從的POP3/SMTP/IMAP三個(gè)協(xié)議的簡(jiǎn)述
SMTP(Simple Mail Transfer Protocol):簡(jiǎn)單郵件傳輸協(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é)議。
簡(jiǎn)而言之,SMTP是發(fā)郵件必須遵從的標(biāo)準(zhǔn),POP3是接收郵件要遵從的標(biāo)準(zhǔn),而IMAP是對(duì)POP3協(xié)議的升級(jí),日常工作中,我們主要使用的是發(fā)郵件操作。
四、業(yè)務(wù)代碼
4.1、新增MailService接口,并聲明4個(gè)發(fā)送不同類型郵件的方法
注:入?yún)⒍嘤?個(gè)的情況下,通常也會(huì)把入?yún)⒎庋b為一個(gè)實(shí)體Bean,方便起見,這里就不封裝了。
package com.example.demo.service;
/**
* @author xyp
* @create 2022-10-07 12:57
* @describe 郵件發(fā)送接口,定義發(fā)送不同類型郵件的方法
*/
public interface MailService {
/**
* 發(fā)送簡(jiǎn)單文本的郵件
* @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 //沒有這個(gè)注解,發(fā)送郵件時(shí)可能會(huì)引發(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) 對(duì)應(yīng),才能設(shè)置圖片成功,
// 具體可以參見,下面 4.3.3 單元測(cè)試的參數(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)查看
如下圖所示,核心的幾個(gè)類,都被紅色的框,框選著的,其他一些package與本項(xiàng)目無關(guān)。

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

5.1、發(fā)送純文本郵件的測(cè)試
5.1.1、測(cè)試代碼編寫
package com.example.demo;
import com.example.demo.service.MailService;
import org.junit.Assert;//注意這個(gè)包是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)題:簡(jiǎn)單的文本發(fā)送測(cè)試";
String content="簡(jiǎn)單的文本";
Assert.assertTrue(mailService.sendSimpleText(to,title,content));
}
}
5.1.2、運(yùn)行查看,報(bào)錯(cuò)小插曲

初次運(yùn)行,可能會(huì)報(bào)如下錯(cuò)誤

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

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



至此,第一個(gè)純文本郵件發(fā)送,測(cè)試成功!
5.2、發(fā)送純HTML文本測(cè)試
5.2.1、測(cè)試代碼編寫
@Test
public void sendHtml(){
String to="871038951@qq.com";
String title="標(biāo)題:Html文本發(fā)送測(cè)試";
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)入郵箱,并打開


至此,第二個(gè)發(fā)送Html的測(cè)試,測(cè)試成功!
5.3、發(fā)送帶圖片的HTML測(cè)試
5.3.1、測(cè)試代碼編寫
@Test
public void sendWithImageHtml(){
String to="871038951@qq.com";
String title="標(biāo)題:帶有圖片的Html發(fā)送測(cè)試";
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)入郵箱,查看郵件


至此,第三個(gè)發(fā)送帶圖片的Html郵件,測(cè)試成功!
5.4、發(fā)送帶附件的測(cè)試
5.4.1、測(cè)試代碼編寫
@Test
public void sendWithWithEnclosure(){
String to="871038951@qq.com";
String title="標(biāo)題:帶有附件的郵件發(fā)送測(cè)試";
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é)果

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

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


經(jīng)測(cè)試,下載后,附件可以正常打開。
至此,各個(gè)案例都演示完畢!
案例雖然簡(jiǎn)單,總的來說,這個(gè)幾個(gè)方法還是有一定的局限性,不過它為我們今后整合一個(gè)功能更齊全的郵件發(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)容相同的郵件,會(huì)被判定為垃圾郵件,可能會(huì)被攔截。
到此這篇關(guān)于SpringBoot整合郵件發(fā)送的四種方法的文章就介紹到這了,更多相關(guān)SpringBoot郵件發(fā)送內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 使用SpringBoot發(fā)送郵件的方法詳解
- SpringBoot實(shí)現(xiàn)定時(shí)發(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ā)送微信公眾號(hào)推送功能
- Spring?Boot整合郵箱發(fā)送郵件實(shí)例
- SpringBoot實(shí)現(xiàn)發(fā)送電子郵件
- SpringBoot整合JavaMail實(shí)現(xiàn)發(fā)郵件的項(xiàng)目實(shí)踐
相關(guān)文章
ThreadPoolExecutor線程池原理及其execute方法(詳解)
下面小編就為大家?guī)硪黄猅hreadPoolExecutor線程池原理及其execute方法(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
使用mybatis的typeHandler對(duì)clob進(jìn)行流讀寫方式
這篇文章主要介紹了使用mybatis的typeHandler對(duì)clob進(jìn)行流讀寫方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
基于maven install 沒反應(yīng)的解決方法
下面小編就為大家?guī)硪黄趍aven install 沒反應(yīng)的解決方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
Java基于中介者模式實(shí)現(xiàn)多人聊天室功能示例
這篇文章主要介紹了Java基于中介者模式實(shí)現(xiàn)多人聊天室功能,詳細(xì)分析了中介者模式的概念、原理以及使用中介模式實(shí)現(xiàn)多人聊天的步驟、操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-05-05
Java 客戶端操作 FastDFS 實(shí)現(xiàn)文件上傳下載替換刪除功能
這篇文章主要介紹了Java 客戶端操作 FastDFS 實(shí)現(xiàn)文件上傳下載替換刪除功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
解決若依pageHelper在動(dòng)態(tài)切換數(shù)據(jù)源問題
這篇文章主要介紹了解決pageHelper在動(dòng)態(tài)切換數(shù)據(jù)源問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01

