SpringBoot整合郵件發(fā)送的四種方法
前言
郵件發(fā)送,聽著很神秘,然而對于Spring Boot來說,這個(gè)功能已被集成好,只需引入spring-boot-starter-mail依賴后,少量代碼即可實(shí)現(xiàn)大部分郵件發(fā)送需求。
因發(fā)送郵件的方法只是在調(diào)用上,略有改動(dòng)(比如,設(shè)置參數(shù)是否包含有ture),故在代碼編排上,寫在一個(gè)類中了,后面單元測試時(shí)分開測試即可。
¥¥¥¥¥具體操作步驟如下¥¥¥¥¥
一、創(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ā)送者);密碼是對應(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)碼
我的賬號默認(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é)議的簡述
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個(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ā)送簡單文本的郵件 * @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) 對應(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)查看
如下圖所示,核心的幾個(gè)類,都被紅色的框,框選著的,其他一些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;//注意這個(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)題:簡單的文本發(fā)送測試"; String content="簡單的文本"; 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ā)送,測試成功!
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)入郵箱,并打開
至此,第二個(gè)發(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)入郵箱,查看郵件
至此,第三個(gè)發(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)測試,下載后,附件可以正常打開。
至此,各個(gè)案例都演示完畢!
案例雖然簡單,總的來說,這個(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)容請搜索腳本之家以前的文章或繼續(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ā)送微信公眾號推送功能
- 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ì),具有一定的借鑒價(jià)值,需要的可以參考一下2022-10-10java實(shí)現(xiàn)優(yōu)酷視頻地址解析示例代碼分享
最近做了一個(gè)在線視頻的下載器,需要解析youku的視頻,獲得真正的視頻地址,現(xiàn)在把解析過程記錄下來以供參考2014-01-01java枚舉enum,根據(jù)value值獲取key鍵的操作
這篇文章主要介紹了java枚舉enum,根據(jù)value值獲取key鍵的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02java實(shí)現(xiàn)后臺(tái)圖片跨域上傳功能
這篇文章主要給大家介紹了關(guān)于java實(shí)現(xiàn)后臺(tái)圖片跨域上傳功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Java中三種零拷貝的實(shí)現(xiàn)示例以及對比詳解
這篇文章主要介紹了Java中三種零拷貝的實(shí)現(xiàn)示例以及對比詳解,本文主要是介紹幾種零拷貝的實(shí)現(xiàn)示例,以及與最傳統(tǒng)的做一個(gè)對比,看看在效率上到底有多大的提升,需要的朋友可以參考下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