溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

SpringBoot實(shí)現(xiàn)郵件發(fā)送必會的5種姿勢是什么

發(fā)布時(shí)間:2021-10-13 10:17:02 來源:億速云 閱讀:91 作者:柒染 欄目:編程語言

今天就跟大家聊聊有關(guān)SpringBoot實(shí)現(xiàn)郵件發(fā)送必會的5種姿勢是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

前言

郵件發(fā)送其實(shí)是一個(gè)非常常見的需求,用戶注冊,找回密碼等地方,都會用到,使用 JavaSE 代碼發(fā)送郵件,步驟還是挺繁瑣的,Spring Boot 中對于郵件發(fā)送,提供了相關(guān)的自動(dòng)化配置類,使得郵件發(fā)送變得非常容易,我們就來一探究竟!看看使用 Spring Boot 發(fā)送郵件的 5 中姿勢。

郵件基礎(chǔ)

我們經(jīng)常會聽到各種各樣的郵件協(xié)議,比如 SMTP、POP3、IMAP ,那么這些協(xié)議有什么作用,有什么區(qū)別?我們先來討論一下這個(gè)問題。

SMTP 是一個(gè)基于 TCP/IP 的應(yīng)用層協(xié)議,江湖地位有點(diǎn)類似于 HTTP,SMTP 服務(wù)器默認(rèn)監(jiān)聽的端口號為 25 ??吹竭@里,小伙伴們可能會想到既然 SMTP 協(xié)議是基于 TCP/IP 的應(yīng)用層協(xié)議,那么我是不是也可以通過 Socket 發(fā)送一封郵件呢?回答是肯定的。

生活中我們投遞一封郵件要經(jīng)過如下幾個(gè)步驟:

  1. 深圳的小王先將郵件投遞到深圳的郵局  深圳的郵局將郵件運(yùn)送到上海的郵局  上海的小張來郵局取郵件

這是一個(gè)縮減版的生活中郵件發(fā)送過程。這三個(gè)步驟可以分別對應(yīng)我們的郵件發(fā)送過程,假設(shè)從 aaa@qq.com 發(fā)送郵件到 111@163.com :

  1. aaa@qq.com 先將郵件投遞到騰訊的郵件服務(wù)器  騰訊的郵件服務(wù)器將我們的郵件投遞到網(wǎng)易的郵件服務(wù)器  111@163.com 登錄網(wǎng)易的郵件服務(wù)器查看郵件

郵件投遞大致就是這個(gè)過程,這個(gè)過程就涉及到了多個(gè)協(xié)議,我們來分別看一下。

SMTP 協(xié)議全稱為 Simple Mail Transfer Protocol,譯作簡單郵件傳輸協(xié)議,它定義了郵件客戶端軟件與 SMTP 服務(wù)器之間,以及 SMTP 服務(wù)器與 SMTP 服務(wù)器之間的通信規(guī)則。

也就是說 aaa@qq.com 用戶先將郵件投遞到騰訊的 SMTP 服務(wù)器這個(gè)過程就使用了 SMTP 協(xié)議,然后騰訊的 SMTP 服務(wù)器將郵件投遞到網(wǎng)易的 SMTP 服務(wù)器這個(gè)過程也依然使用了 SMTP 協(xié)議,SMTP 服務(wù)器就是用來收郵件。

而 POP3 協(xié)議全稱為 Post Office Protocol ,譯作郵局協(xié)議,它定義了郵件客戶端與 POP3 服務(wù)器之間的通信規(guī)則,那么該協(xié)議在什么場景下會用到呢?當(dāng)郵件到達(dá)網(wǎng)易的 SMTP 服務(wù)器之后, 111@163.com 用戶需要登錄服務(wù)器查看郵件,這個(gè)時(shí)候就該協(xié)議就用上了:郵件服務(wù)商都會為每一個(gè)用戶提供專門的郵件存儲空間,SMTP 服務(wù)器收到郵件之后,就將郵件保存到相應(yīng)用戶的郵件存儲空間中,如果用戶要讀取郵件,就需要通過郵件服務(wù)商的 POP3 郵件服務(wù)器來完成。

最后,可能也有小伙伴們聽說過 IMAP 協(xié)議,這個(gè)協(xié)議是對 POP3 協(xié)議的擴(kuò)展,功能更強(qiáng),作用類似,這里不再贅述。

準(zhǔn)備工作

目前國內(nèi)大部分的郵件服務(wù)商都不允許直接使用用戶名/密碼的方式來在代碼中發(fā)送郵件,都是要先申請授權(quán)碼,這里以 QQ 郵箱為例,向大家演示授權(quán)碼的申請流程:首先我們需要先登錄 QQ 郵箱網(wǎng)頁版,點(diǎn)擊上方的設(shè)置按鈕:

然后點(diǎn)擊賬戶選項(xiàng)卡:

在賬戶選項(xiàng)卡中找到開啟POP3/SMTP選項(xiàng),如下:

點(diǎn)擊開啟,開啟相關(guān)功能,開啟過程需要手機(jī)號碼驗(yàn)證,按照步驟操作即可,不贅述。開啟成功之后,即可獲取一個(gè)授權(quán)碼,將該號碼保存好,一會使用。

項(xiàng)目創(chuàng)建

接下來,我們就可以創(chuàng)建項(xiàng)目了,Spring Boot 中,對于郵件發(fā)送提供了自動(dòng)配置類,開發(fā)者只需要加入相關(guān)依賴,然后配置一下郵箱的基本信息,就可以發(fā)送郵件了。

首先創(chuàng)建一個(gè) Spring Boot 項(xiàng)目,引入郵件發(fā)送依賴:

創(chuàng)建完成后,項(xiàng)目依賴如下:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>

配置郵箱基本信息

項(xiàng)目創(chuàng)建成功后,接下來在 application.properties 中配置郵箱的基本信息:

spring.mail.host=smtp.qq.comspring.mail.port=587spring.mail.username=1510161612@qq.comspring.mail.password=ubknfzhjkhrbbabespring.mail.default-encoding=UTF-8spring.mail.properties.mail.smtp.socketFactoryClass=javax.net.ssl.SSLSocketFactoryspring.mail.properties.mail.debug=true

配置含義分別如下:

配置 SMTP 服務(wù)器地址  SMTP 服務(wù)器的端口  配置郵箱用戶名  配置密碼,注意,不是真正的密碼,而是剛剛申請到的授權(quán)碼  默認(rèn)的郵件編碼  配飾 SSL 加密工廠  表示開啟 DEBUG 模式,這樣,郵件發(fā)送過程的日志會在控制臺打印出來,方便排查錯(cuò)誤

如果不知道 smtp 服務(wù)器的端口或者地址的的話,可以參考 騰訊的郵箱文檔

https://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=371

做完這些之后,Spring Boot 就會自動(dòng)幫我們配置好郵件發(fā)送類,相關(guān)的配置在 org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration 類中,部分源碼如下:

@Configuration@ConditionalOnClass({ MimeMessage.class, MimeType.class, MailSender.class })@ConditionalOnMissingBean(MailSender.class)@Conditional(MailSenderCondition.class)@EnableConfigurationProperties(MailProperties.class)@Import({ MailSenderJndiConfiguration.class, MailSenderPropertiesConfiguration.class })public class MailSenderAutoConfiguration {}

從這段代碼中,可以看到,導(dǎo)入了另外一個(gè)配置 MailSenderPropertiesConfiguration 類,這個(gè)類中,提供了郵件發(fā)送相關(guān)的工具類:

@Configuration@ConditionalOnProperty(prefix = "spring.mail", name = "host")class MailSenderPropertiesConfiguration { private final MailProperties properties; MailSenderPropertiesConfiguration(MailProperties properties) {  this.properties = properties; } @Bean @ConditionalOnMissingBean public JavaMailSenderImpl mailSender() {  JavaMailSenderImpl sender = new JavaMailSenderImpl();  applyProperties(sender);  return sender; }}

可以看到,這里創(chuàng)建了一個(gè) JavaMailSenderImpl 的實(shí)例, JavaMailSenderImpl 是 JavaMailSender 的一個(gè)實(shí)現(xiàn),我們將使用 JavaMailSenderImpl 來完成郵件的發(fā)送工作。

做完如上兩步,郵件發(fā)送的準(zhǔn)備工作就算是完成了,接下來就可以直接發(fā)送郵件了。

具體的發(fā)送,有 5 種不同的方式,我們一個(gè)一個(gè)來看。

發(fā)送簡單郵件

簡單郵件就是指郵件內(nèi)容是一個(gè)普通的文本文檔:

@AutowiredJavaMailSender javaMailSender;@Testpublic void sendSimpleMail() { SimpleMailMessage message = new SimpleMailMessage(); message.setSubject("這是一封測試郵件"); message.setFrom("1510161612@qq.com"); message.setTo("25xxxxx755@qq.com"); message.setCc("37xxxxx37@qq.com"); message.setBcc("14xxxxx098@qq.com"); message.setSentDate(new Date()); message.setText("這是測試郵件的正文"); javaMailSender.send(message);}

從上往下,代碼含義分別如下:

  1. 構(gòu)建一個(gè)郵件對象  設(shè)置郵件主題  設(shè)置郵件發(fā)送者  設(shè)置郵件接收者,可以有多個(gè)接收者  設(shè)置郵件抄送人,可以有多個(gè)抄送人  設(shè)置隱秘抄送人,可以有多個(gè)  設(shè)置郵件發(fā)送日期  設(shè)置郵件的正文  發(fā)送郵件

最后執(zhí)行該方法,就可以實(shí)現(xiàn)郵件的發(fā)送,發(fā)送效果圖如下:

發(fā)送帶附件的郵件

郵件的附件可以是圖片,也可以是普通文件,都是支持的。

@Testpublic void sendAttachFileMail() throws MessagingException { MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true); helper.setSubject("這是一封測試郵件"); helper.setFrom("1510161612@qq.com"); helper.setTo("25xxxxx755@qq.com"); helper.setCc("37xxxxx37@qq.com"); helper.setBcc("14xxxxx098@qq.com"); helper.setSentDate(new Date()); helper.setText("這是測試郵件的正文"); helper.addAttachment("javaboy.jpg",new File("C:\\Users\\sang\\Downloads\\javaboy.png")); javaMailSender.send(mimeMessage);}

注意這里在構(gòu)建郵件對象上和前文有所差異,這里是通過 javaMailSender 來獲取一個(gè)復(fù)雜郵件對象,然后再利用 MimeMessageHelper 對郵件進(jìn)行配置,MimeMessageHelper 是一個(gè)郵件配置的輔助工具類,創(chuàng)建時(shí)候的 true 表示構(gòu)建一個(gè) multipart message 類型的郵件,有了 MimeMessageHelper 之后,我們針對郵件的配置都是由 MimeMessageHelper 來代勞。

最后通過 addAttachment 方法來添加一個(gè)附件。

執(zhí)行該方法,郵件發(fā)送效果圖如下:

發(fā)送帶圖片資源的郵件

圖片資源和附件有什么區(qū)別呢?圖片資源是放在郵件正文中的,即一打開郵件,就能看到圖片。但是一般來說,不建議使用這種方式,一些公司會對郵件內(nèi)容的大小有限制(因?yàn)檫@種方式是將圖片一起發(fā)送的)。

@Testpublic void sendImgResMail() throws MessagingException { MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setSubject("這是一封測試郵件"); helper.setFrom("1510161612@qq.com"); helper.setTo("25xxxxx755@qq.com"); helper.setCc("37xxxxx37@qq.com"); helper.setBcc("14xxxxx098@qq.com"); helper.setSentDate(new Date()); helper.setText("<p>hello 大家好,這是一封測試郵件,這封郵件包含兩種圖片,分別如下</p><p>第一張圖片:</p><img src='cid:p01'/><p>第二張圖片:</p><img src='cid:p02'/>",true); helper.addInline("p01",new FileSystemResource(new File("C:\\Users\\sang\\Downloads\\javaboy.png"))); helper.addInline("p02",new FileSystemResource(new File("C:\\Users\\sang\\Downloads\\javaboy2.png"))); javaMailSender.send(mimeMessage);}

這里的郵件 text 是一個(gè) HTML 文本,里邊涉及到的圖片資源先用一個(gè)占位符占著,setText 方法的第二個(gè)參數(shù) true 表示第一個(gè)參數(shù)是一個(gè) HTML 文本。

setText 之后,再通過 addInline 方法來添加圖片資源。

最后執(zhí)行該方法,發(fā)送郵件,效果如下:

在公司實(shí)際開發(fā)中,第一種和第三種都不是使用最多的郵件發(fā)送方案。因?yàn)檎碚f,郵件的內(nèi)容都是比較的豐富的,所以大部分郵件都是通過 HTML 來呈現(xiàn)的,如果直接拼接 HTML 字符串,這樣以后不好維護(hù),為了解決這個(gè)問題,一般郵件發(fā)送,都會有相應(yīng)的郵件模板。最具代表性的兩個(gè)模板就是 Freemarker 模板和 Thyemeleaf 模板了。

使用 Freemarker 作郵件模板

首先需要引入 Freemarker 依賴:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId></dependency>

然后在 resources/templates 目錄下創(chuàng)建一個(gè) mail.ftl 作為郵件發(fā)送模板:

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><p>hello 歡迎加入 xxx 大家庭,您的入職信息如下:</p><table border="1"> <tr> <td>姓名</td> <td>${username}</td> </tr> <tr> <td>工號</td> <td>${num}</td> </tr> <tr> <td>薪水</td> <td>${salary}</td> </tr></table><p >一起努力創(chuàng)造輝煌</p></body></html>

接下來,將郵件模板渲染成 HTML ,然后發(fā)送即可。

@Testpublic void sendFreemarkerMail() throws MessagingException, IOException, TemplateException { MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setSubject("這是一封測試郵件"); helper.setFrom("1510161612@qq.com"); helper.setTo("25xxxxx755@qq.com"); helper.setCc("37xxxxx37@qq.com"); helper.setBcc("14xxxxx098@qq.com"); helper.setSentDate(new Date()); //構(gòu)建 Freemarker 的基本配置 Configuration configuration = new Configuration(Configuration.VERSION_2_3_0); // 配置模板位置 ClassLoader loader = MailApplication.class.getClassLoader(); configuration.setClassLoaderForTemplateLoading(loader, "templates"); //加載模板 Template template = configuration.getTemplate("mail.ftl"); User user = new User(); user.setUsername("javaboy"); user.setNum(1); user.setSalary((double) 99999); StringWriter out = new StringWriter(); //模板渲染,渲染的結(jié)果將被保存到 out 中 ,將out 中的 html 字符串發(fā)送即可 template.process(user, out); helper.setText(out.toString(),true); javaMailSender.send(mimeMessage);}

需要注意的是,雖然引入了 Freemarker 的自動(dòng)化配置,但是我們在這里是直接 new Configuration 來重新配置 Freemarker 的,所以 Freemarker 默認(rèn)的配置這里不生效,因此,在填寫模板位置時(shí),值為 templates 。

調(diào)用該方法,發(fā)送郵件,效果圖如下:

使用 Thymeleaf 作郵件模板

推薦在 Spring Boot 中使用 Thymeleaf 來構(gòu)建郵件模板。因?yàn)?Thymeleaf 的自動(dòng)化配置提供了一個(gè) TemplateEngine,通過 TemplateEngine 可以方便的將 Thymeleaf 模板渲染為 HTML ,同時(shí),Thymeleaf 的自動(dòng)化配置在這里是繼續(xù)有效的 。

首先,引入 Thymeleaf 依賴:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>

然后,創(chuàng)建 Thymeleaf 郵件模板:

<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>Title</title></head><body><p>hello 歡迎加入 xxx 大家庭,您的入職信息如下:</p><table border="1"> <tr> <td>姓名</td> <td th:text="${username}"></td> </tr> <tr> <td>工號</td> <td th:text="${num}"></td> </tr> <tr> <td>薪水</td> <td th:text="${salary}"></td> </tr></table><p >一起努力創(chuàng)造輝煌</p></body></html>

接下來發(fā)送郵件:

@AutowiredTemplateEngine templateEngine;@Testpublic void sendThymeleafMail() throws MessagingException { MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setSubject("這是一封測試郵件"); helper.setFrom("1510161612@qq.com"); helper.setTo("25xxxxx755@qq.com"); helper.setCc("37xxxxx37@qq.com"); helper.setBcc("14xxxxx098@qq.com"); helper.setSentDate(new Date()); Context context = new Context(); context.setVariable("username", "javaboy"); context.setVariable("num","000001"); context.setVariable("salary", "99999"); String process = templateEngine.process("mail.html", context); helper.setText(process,true); javaMailSender.send(mimeMessage);}

看完上述內(nèi)容,你們對SpringBoot實(shí)現(xiàn)郵件發(fā)送必會的5種姿勢是什么有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI