在咱們這個時代,郵件服務不論是對於工做上的交流,仍是平時的各類郵件通知,都是一個十分重要的存在。Java 從很早時候就能夠經過 Java mail 支持郵件服務。Spring 更是對 Java mail 進行了進一步的封裝,抽象出了 JavaMailSender
. 後來隨着 Springboot 的出現,理所固然的出現了 spring-boot-starter-mail
. 無論怎麼說,每次的封裝都讓使用變得愈來愈簡單。html
<!-- more -->java
建立 Springboot 項目不提,先看一下整體目錄結構。 git
直接引入 Springboot 郵件服務所需的依賴。github
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 郵件服務 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <!-- Thymeleaf 模版,用於發送模版郵件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
使用郵件服務須要配置本身可使用的郵箱信息,通常須要配置發送協議 SMTP、郵箱賬號(本次以126郵箱爲例)、郵箱密碼以及編碼格式。web
spring.mail.host=smtp.126.com spring.mail.port=25 # 你的郵箱地址 spring.mail.username=youremail@126.com # 你的受權碼(126 和 163 以及 qq 郵箱 都須要受權碼登陸,沒有受權碼的直接登陸網頁版郵箱設置裏設置) spring.mail.password=password spring.mail.default-encoding=UTF-8
文本郵件是最簡單也是最基礎的一種郵件,使用 Spring 封裝的 JavaMailSender
直接發送就能夠了。spring
建立 MailService
類,注入 JavaMailSender
用於發送郵件,使用 @Value("${spring.mail.username}")
綁定配置文件中的參數用於設置郵件發送的來郵箱。使用 @Service
註解把 MailService
注入到 Spring 容器,使用 Lombok
的 @Slf4j
引入日誌。springboot
/** * <p> * 郵件服務 * * @Author niujinpeng * @Date 2019/3/10 21:45 */ @Service @Slf4j public class MailService { @Value("${spring.mail.username}") private String from; @Autowired private JavaMailSender mailSender; /** * 發送簡單文本郵件 * * @param to * @param subject * @param content */ public void sendSimpleTextMail(String to, String subject, String content) { SimpleMailMessage message = new SimpleMailMessage(); message.setTo(to); message.setSubject(subject); message.setText(content); message.setFrom(from); mailSender.send(message); log.info("【文本郵件】成功發送!to={}", to); } }
建立 Springboot 的單元測試類測試文本郵件,實驗中的收信人爲了方便,都設置成了本身的郵箱。微信
@RunWith(SpringRunner.class) @SpringBootTest public class MailServiceTest { @Autowired private MailService mailService; @Autowired private TemplateEngine templateEngine; @Test public void sendSimpleTextMailTest() { String to = "youemail@126.com"; String subject = "Springboot 發送簡單文本郵件"; String content = "<p>第一封 Springboot 簡單文本郵件</p>"; mailService.sendSimpleTextMail(to, subject, content); } }
運行單元測試,測試文本郵件的發送。app
PS:若是運行報出異常 AuthenticationFailedException: 535 Error
. 通常都是用戶名和密碼有誤。異步
Caused by: javax.mail.AuthenticationFailedException: 535 Error: authentication failed at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:965) at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:876) at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:780) at javax.mail.Service.connect(Service.java:366) at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:517) at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:436) ... 34 more
正常運行輸出成功發送的日誌。
2019-03-11 23:35:14.743 INFO 13608 --- [ main] n.codingme.boot.service.MailServiceTest : Started MailServiceTest in 3.964 seconds (JVM running for 5.749) 2019-03-11 23:35:24.718 INFO 13608 --- [ main] net.codingme.boot.service.MailService : 【文本郵件】成功發送!to=youemail@126.com
查看郵箱中的收信。
文本郵件正常收到,同時可見文本郵件中的 HTML 標籤也不會被解析。
在上面的 MailService
類裏新加一個方法 sendHtmlMail
,用於測試 HTML 郵件。
/** * 發送 HTML 郵件 * * @param to * @param subject * @param content * @throws MessagingException */ public void sendHtmlMail(String to, String subject, String content) throws MessagingException { MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper messageHelper = new MimeMessageHelper(message, true); messageHelper.setFrom(from); messageHelper.setTo(to); messageHelper.setSubject(subject); // true 爲 HTML 郵件 messageHelper.setText(content, true); mailSender.send(message); log.info("【HTML 郵件】成功發送!to={}", to); }
在測試方法中增長 HTML 郵件測試方法。
@Test public void sendHtmlMailTest() throws MessagingException { String to = "youremail@126.com"; String subject = "Springboot 發送 HTML 郵件"; String content = "<h2>Hi~</h2><p>第一封 Springboot HTML 郵件</p>"; mailService.sendHtmlMail(to, subject, content); }
運行單元測試,查看收信狀況。
HTML 郵件正常收到,HTML 標籤也被解析成對應的樣式。
在上面的 MailService
類裏新加一個方法 sendAttachmentMail
,用於測試 附件郵件。
/** * 發送帶附件的郵件 * * @param to * @param subject * @param content * @param fileArr */ public void sendAttachmentMail(String to, String subject, String content, String... fileArr) throws MessagingException { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true); messageHelper.setFrom(from); messageHelper.setTo(to); messageHelper.setSubject(subject); messageHelper.setText(content, true); // 添加附件 for (String filePath : fileArr) { FileSystemResource fileResource = new FileSystemResource(new File(filePath)); if (fileResource.exists()) { String filename = fileResource.getFilename(); messageHelper.addAttachment(filename, fileResource); } } mailSender.send(mimeMessage); log.info("【附件郵件】成功發送!to={}", to); }
在測試方法中增長附件郵件測試方法。
@Test public void sendAttachmentTest() throws MessagingException { String to = "youremail@126.com"; String subject = "Springboot 發送 HTML 附件郵件"; String content = "<h2>Hi~</h2><p>第一封 Springboot HTML 附件郵件</p>"; String filePath = "pom.xml"; mailService.sendAttachmentMail(to, subject, content, filePath, filePath); }
運行單元測試,查看收信狀況。
帶附件的郵件正常收到,多個附件的實現方式同理。
圖片郵件和其餘的郵件方式略有不一樣,圖片郵件須要先在內容中定義好圖片的位置並出給一個記錄 ID ,而後在把圖片加到郵件中的對於的 ID 位置。
在上面的 MailService
類裏新加一個方法 sendImgMail
,用於測試 附件郵件。
/** * 發送帶圖片的郵件 * * @param to * @param subject * @param content * @param imgMap */ public void sendImgMail(String to, String subject, String content, Map<String, String> imgMap) throws MessagingException { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true); messageHelper.setFrom(from); messageHelper.setTo(to); messageHelper.setSubject(subject); messageHelper.setText(content, true); // 添加圖片 for (Map.Entry<String, String> entry : imgMap.entrySet()) { FileSystemResource fileResource = new FileSystemResource(new File(entry.getValue())); if (fileResource.exists()) { String filename = fileResource.getFilename(); messageHelper.addInline(entry.getKey(), fileResource); } } mailSender.send(mimeMessage); log.info("【圖片郵件】成功發送!to={}", to); }
在測試方法中增長圖片郵件測試方法,測試方法中使用的 apple.png 是項目裏的一個圖片。能夠看上面的項目結構。
@Test public void sendImgTest() throws MessagingException { String to = "youremail@126.com"; String subject = "Springboot 發送 HTML 圖片郵件"; String content = "<h2>Hi~</h2><p>第一封 Springboot HTML 圖片郵件</p><br/><img src=\"cid:img01\" /><img src=\"cid:img02\" />"; String imgPath = "apple.png"; Map<String, String> imgMap = new HashMap<>(); imgMap.put("img01", imgPath); imgMap.put("img02", imgPath); mailService.sendImgMail(to, subject, content, imgMap); }
運行單元測試,查看收信狀況。
兩個圖片正常顯示在郵件裏。
模版郵件的用處很普遍,像常常收到的註冊成功郵件或者是操做通知郵件等都是模版郵件,模版郵件每每只須要更改其中的幾個變量。Springboot 中的模版郵件首選須要選擇一款模版引擎,在引入依賴的時候已經增長了模版引擎 Thymeleaf
.
模版郵件首先須要一個郵件模版,咱們在 Templates
下新建一個 HTML
文件 RegisterSuccess.html
. 其中的 username 是給咱們自定義的。
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>註冊成功通知</title> </head> <body> <p>[[${username}]],您好! </p> <p> 新的公鑰已添加到你的帳戶:<br/> 標題: HP-WIN10 <br/> 若是公鑰沒法使用,你能夠在這裏從新添加: SSH Keys </p> </body> </html>
在郵件服務 MailService
中注入模版引擎,而後編寫郵件模版發送代碼。
@Autowired private TemplateEngine templateEngine; /** * 發送模版郵件 * * @param to * @param subject * @param paramMap * @param template * @throws MessagingException */ public void sendTemplateMail(String to, String subject, Map<String, Object> paramMap, String template) throws MessagingException { Context context = new Context(); // 設置變量的值 context.setVariables(paramMap); String emailContent = templateEngine.process(template, context); sendHtmlMail(to, subject, emailContent); log.info("【模版郵件】成功發送!paramsMap={},template={}", paramMap, template); }
在單元單元測試中增長模版郵件測試方法,而後發送郵件測試。
@Test public void sendTemplateMailTest() throws MessagingException { String to = "youremail@126.com"; String subject = "Springboot 發送 模版郵件"; Map<String, Object> paramMap = new HashMap(); paramMap.put("username", "Darcy"); mailService.sendTemplateMail(to, subject, paramMap, "RegisterSuccess"); }
查看收信狀況。
能夠發現模版郵件已經正常發送了。
上面的例子中,是 Springboot 郵件服務的基本用法,代碼也有不少重複,和實際的使用狀況相比還有不少不足,好比缺乏異常處理機制
,在發送失敗時的重試機制
也沒有,實際狀況中郵件服務每每對實時性不高,多說狀況下會用於異步請求
。
文章相關代碼已經上傳 Github Spring Boot 相關整合 - 郵件服務。
<div id="MySignature" style="max-width:500px;display: block;border: solid 1px #E5E5E5;padding: 10px; background: #FFFEFE url(https://img2018.cnblogs.com/blog/1202902/201908/1202902-20190806114612975-1863336558.png) no-repeat scroll 1% 50%; padding-left: 180px;height: 160px;"> <div style="padding-top: 10px;">本文做者:<b>雪漫士兵</b><br> 個人微信:wn8398<br> 原文出處:<a href="https://www.codingme.net">www.codingme.net</a> <!-- 交流羣號:139267796 <br> --> <div style="margin-top:10px;margin-bottom:5px;">本片文章是博主原創文章,歡迎轉載,轉載時在明顯位置註明原文連接便可。</div> <b>若是以爲這篇內容有趣好玩有幫助,不妨關注公衆號點個好看推薦。</b> </div> <div style="clear: both"></div> </div>