摘要:也就是說用戶先將郵件投遞到騰訊的服務器這個過程就使用了協議,然后騰訊的服務器將郵件投遞到網易的服務器這個過程也依然使用了協議,服務器就是用來收郵件。
郵件發送其實是一個非常常見的需求,用戶注冊,找回密碼等地方,都會用到,使用 JavaSE 代碼發送郵件,步驟還是挺繁瑣的,Spring Boot 中對于郵件發送,提供了相關的自動化配置類,使得郵件發送變得非常容易,本文我們就來一探究竟!看看使用 Spring Boot 發送郵件的 5 中姿勢。
郵件基礎我們經常會聽到各種各樣的郵件協議,比如 SMTP、POP3、IMAP ,那么這些協議有什么作用,有什么區別?我們先來討論一下這個問題。
SMTP 是一個基于 TCP/IP 的應用層協議,江湖地位有點類似于 HTTP,SMTP 服務器默認監聽的端口號為 25 。看到這里,小伙伴們可能會想到既然 SMTP 協議是基于 TCP/IP 的應用層協議,那么我是不是也可以通過 Socket 發送一封郵件呢?回答是肯定的。
生活中我們投遞一封郵件要經過如下幾個步驟:
深圳的小王先將郵件投遞到深圳的郵局
深圳的郵局將郵件運送到上海的郵局
上海的小張來郵局取郵件
這是一個縮減版的生活中郵件發送過程。這三個步驟可以分別對應我們的郵件發送過程,假設從 aaa@qq.com 發送郵件到 111@163.com :
aaa@qq.com 先將郵件投遞到騰訊的郵件服務器
騰訊的郵件服務器將我們的郵件投遞到網易的郵件服務器
111@163.com 登錄網易的郵件服務器查看郵件
郵件投遞大致就是這個過程,這個過程就涉及到了多個協議,我們來分別看一下。
SMTP 協議全稱為 Simple Mail Transfer Protocol,譯作簡單郵件傳輸協議,它定義了郵件客戶端軟件與 SMTP 服務器之間,以及 SMTP 服務器與 SMTP 服務器之間的通信規則。
也就是說 aaa@qq.com 用戶先將郵件投遞到騰訊的 SMTP 服務器這個過程就使用了 SMTP 協議,然后騰訊的 SMTP 服務器將郵件投遞到網易的 SMTP 服務器這個過程也依然使用了 SMTP 協議,SMTP 服務器就是用來收郵件。
而 POP3 協議全稱為 Post Office Protocol ,譯作郵局協議,它定義了郵件客戶端與 POP3 服務器之間的通信規則,那么該協議在什么場景下會用到呢?當郵件到達網易的 SMTP 服務器之后, 111@163.com 用戶需要登錄服務器查看郵件,這個時候就該協議就用上了:郵件服務商都會為每一個用戶提供專門的郵件存儲空間,SMTP 服務器收到郵件之后,就將郵件保存到相應用戶的郵件存儲空間中,如果用戶要讀取郵件,就需要通過郵件服務商的 POP3 郵件服務器來完成。
最后,可能也有小伙伴們聽說過 IMAP 協議,這個協議是對 POP3 協議的擴展,功能更強,作用類似,這里不再贅述。
準備工作目前國內大部分的郵件服務商都不允許直接使用用戶名/密碼的方式來在代碼中發送郵件,都是要先申請授權碼,這里以 QQ 郵箱為例,向大家演示授權碼的申請流程:首先我們需要先登錄 QQ 郵箱網頁版,點擊上方的設置按鈕:
然后點擊賬戶選項卡:
在賬戶選項卡中找到開啟POP3/SMTP選項,如下:
點擊開啟,開啟相關功能,開啟過程需要手機號碼驗證,按照步驟操作即可,不贅述。開啟成功之后,即可獲取一個授權碼,將該號碼保存好,一會使用。
項目創建接下來,我們就可以創建項目了,Spring Boot 中,對于郵件發送提供了自動配置類,開發者只需要加入相關依賴,然后配置一下郵箱的基本信息,就可以發送郵件了。
首先創建一個 Spring Boot 項目,引入郵件發送依賴:
創建完成后,項目依賴如下:
org.springframework.boot spring-boot-starter-mail org.springframework.boot spring-boot-starter-web
配置郵箱基本信息
項目創建成功后,接下來在 application.properties 中配置郵箱的基本信息:
spring.mail.host=smtp.qq.com spring.mail.port=587 spring.mail.username=1510161612@qq.com spring.mail.password=ubknfzhjkhrbbabe spring.mail.default-encoding=UTF-8 spring.mail.properties.mail.smtp.socketFactoryClass=javax.net.ssl.SSLSocketFactory spring.mail.properties.mail.debug=true
配置含義分別如下:
配置 SMTP 服務器地址
SMTP 服務器的端口
配置郵箱用戶名
配置密碼,注意,不是真正的密碼,而是剛剛申請到的授權碼
默認的郵件編碼
配飾 SSL 加密工廠
表示開啟 DEBUG 模式,這樣,郵件發送過程的日志會在控制臺打印出來,方便排查錯誤
如果不知道 smtp 服務器的端口或者地址的的話,可以參考 騰訊的郵箱文檔
https://service.mail.qq.com/c...
做完這些之后,Spring Boot 就會自動幫我們配置好郵件發送類,相關的配置在 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 { }
從這段代碼中,可以看到,導入了另外一個配置 MailSenderPropertiesConfiguration 類,這個類中,提供了郵件發送相關的工具類:
@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; } }
可以看到,這里創建了一個 JavaMailSenderImpl 的實例, JavaMailSenderImpl 是 JavaMailSender 的一個實現,我們將使用 JavaMailSenderImpl 來完成郵件的發送工作。
做完如上兩步,郵件發送的準備工作就算是完成了,接下來就可以直接發送郵件了。
具體的發送,有 5 種不同的方式,我們一個一個來看。
發送簡單郵件簡單郵件就是指郵件內容是一個普通的文本文檔:
@Autowired JavaMailSender javaMailSender; @Test public 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); }
從上往下,代碼含義分別如下:
構建一個郵件對象
設置郵件主題
設置郵件發送者
設置郵件接收者,可以有多個接收者
設置郵件抄送人,可以有多個抄送人
設置隱秘抄送人,可以有多個
設置郵件發送日期
設置郵件的正文
發送郵件
最后執行該方法,就可以實現郵件的發送,發送效果圖如下:
發送帶附件的郵件郵件的附件可以是圖片,也可以是普通文件,都是支持的。
@Test public 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:UserssangDownloadsjavaboy.png")); javaMailSender.send(mimeMessage); }
注意這里在構建郵件對象上和前文有所差異,這里是通過 javaMailSender 來獲取一個復雜郵件對象,然后再利用 MimeMessageHelper 對郵件進行配置,MimeMessageHelper 是一個郵件配置的輔助工具類,創建時候的 true 表示構建一個 multipart message 類型的郵件,有了 MimeMessageHelper 之后,我們針對郵件的配置都是由 MimeMessageHelper 來代勞。
最后通過 addAttachment 方法來添加一個附件。
執行該方法,郵件發送效果圖如下:
發送帶圖片資源的郵件圖片資源和附件有什么區別呢?圖片資源是放在郵件正文中的,即一打開郵件,就能看到圖片。但是一般來說,不建議使用這種方式,一些公司會對郵件內容的大小有限制(因為這種方式是將圖片一起發送的)。
@Test public 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("hello 大家好,這是一封測試郵件,這封郵件包含兩種圖片,分別如下
第一張圖片:
第二張圖片:
",true); helper.addInline("p01",new FileSystemResource(new File("C:UserssangDownloadsjavaboy.png"))); helper.addInline("p02",new FileSystemResource(new File("C:UserssangDownloadsjavaboy2.png"))); javaMailSender.send(mimeMessage); }
這里的郵件 text 是一個 HTML 文本,里邊涉及到的圖片資源先用一個占位符占著,setText 方法的第二個參數 true 表示第一個參數是一個 HTML 文本。
setText 之后,再通過 addInline 方法來添加圖片資源。
最后執行該方法,發送郵件,效果如下:
在公司實際開發中,第一種和第三種都不是使用最多的郵件發送方案。因為正常來說,郵件的內容都是比較的豐富的,所以大部分郵件都是通過 HTML 來呈現的,如果直接拼接 HTML 字符串,這樣以后不好維護,為了解決這個問題,一般郵件發送,都會有相應的郵件模板。最具代表性的兩個模板就是 Freemarker 模板和 Thyemeleaf 模板了。
使用 Freemarker 作郵件模板首先需要引入 Freemarker 依賴:
org.springframework.boot spring-boot-starter-freemarker
然后在 resources/templates 目錄下創建一個 mail.ftl 作為郵件發送模板:
Title hello 歡迎加入 xxx 大家庭,您的入職信息如下:
姓名 | ${username} |
工號 | ${num} |
薪水 | ${salary} |
接下來,將郵件模板渲染成 HTML ,然后發送即可。
@Test public 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()); //構建 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(); //模板渲染,渲染的結果將被保存到 out 中 ,將out 中的 html 字符串發送即可 template.process(user, out); helper.setText(out.toString(),true); javaMailSender.send(mimeMessage); }
需要注意的是,雖然引入了 Freemarker 的自動化配置,但是我們在這里是直接 new Configuration 來重新配置 Freemarker 的,所以 Freemarker 默認的配置這里不生效,因此,在填寫模板位置時,值為 templates 。
調用該方法,發送郵件,效果圖如下:
使用 Thymeleaf 作郵件模板推薦在 Spring Boot 中使用 Thymeleaf 來構建郵件模板。因為 Thymeleaf 的自動化配置提供了一個 TemplateEngine,通過 TemplateEngine 可以方便的將 Thymeleaf 模板渲染為 HTML ,同時,Thymeleaf 的自動化配置在這里是繼續有效的 。
首先,引入 Thymeleaf 依賴:
org.springframework.boot spring-boot-starter-thymeleaf
然后,創建 Thymeleaf 郵件模板:
Title hello 歡迎加入 xxx 大家庭,您的入職信息如下:
姓名 | |
工號 | |
薪水 |
接下來發送郵件:
@Autowired TemplateEngine templateEngine; @Test public 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); }
調用該方法,發送郵件,效果圖如下:
好了,這就是我們今天說的 5 種郵件發送姿勢,不知道你掌握了沒有呢?
本文案例已經上傳到 GitHub:https://github.com/lenve/javaboy-code-samples。
有問題歡迎留言討論。
關注公眾號【江南一點雨】,專注于 Spring Boot+微服務以及前后端分離等全棧技術,定期視頻教程分享,關注后回復 Java ,領取松哥為你精心準備的 Java 干貨!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75423.html
摘要:在項目中,為滿足以上要求,我們將大量的參數配置在或文件中,通過注解,我們可以方便的獲取這些參數值使用配置模塊假設我們正在搭建一個發送郵件的模塊。這使得在不影響其他模塊的情況下重構一個模塊中的屬性變得容易。 在編寫項目代碼時,我們要求更靈活的配置,更好的模塊化整合。在 Spring Boot 項目中,為滿足以上要求,我們將大量的參數配置在 application.properties 或...
摘要:在項目中,為滿足以上要求,我們將大量的參數配置在或文件中,通過注解,我們可以方便的獲取這些參數值使用配置模塊假設我們正在搭建一個發送郵件的模塊。這使得在不影響其他模塊的情況下重構一個模塊中的屬性變得容易。 在編寫項目代碼時,我們要求更靈活的配置,更好的模塊化整合。在 Spring Boot 項目中,為滿足以上要求,我們將大量的參數配置在 application.properties 或...
摘要:我拿網易郵箱賬號舉例子,那么我們如何才能讓你的郵箱賬號可以利用第三方發送郵件這里的第三方就是我們即將編寫的程序。 一 前言 測試所使用的環境 測試使用的環境是企業主流的SSM 框架即 SpringMVC+Spring+Mybatis。為了節省時間,我直接使用的是我上次的SSM項目中整合Echarts開發該項目已經搭建完成的SSM環境。 標題說的四種姿勢指的是哪四種姿勢? 發送text...
摘要:慕課網發送郵件學習總結時間年月日星期六說明本文部分內容均來自慕課網。 慕課網《Spring Boot 發送郵件》學習總結 時間:2018年09月08日星期六 說明:本文部分內容均來自慕課網。@慕課網:https://www.imooc.com 教學源碼:https://github.com/ityouknow/... 學習源碼:https://github.com/zccoder...
摘要:前景介紹在日常的工作中,我們經常會用到郵件服務,比如發送驗證碼,找回密碼確認,注冊時郵件驗證等,所以今天在這里進行郵件服務的一些操作。 前景介紹 在日常的工作中,我們經常會用到郵件服務,比如發送驗證碼,找回密碼確認,注冊時郵件驗證等,所以今天在這里進行郵件服務的一些操作。 大致思路 我們要做的其實就是把Java程序作為一個客戶端,然后通過配置SMTP協議去連接我們所使用的發送郵箱(fr...
閱讀 2813·2023-04-25 15:01
閱讀 3012·2021-11-23 10:07
閱讀 3358·2021-10-12 10:12
閱讀 3444·2021-08-30 09:45
閱讀 2184·2021-08-20 09:36
閱讀 3566·2019-08-30 12:59
閱讀 2424·2019-08-26 13:52
閱讀 927·2019-08-26 13:24