在咱們這個時代,郵件服務不論是對於工做上的交流,仍是平時的各類郵件通知,都是一個十分重要的存在。Java 從很早時候就能夠經過 Java mail 支持郵件服務。Spring 更是對 Java mail 進行了進一步的封裝,抽象出了 JavaMailSender
. 後來隨着 Springboot 的出現,理所固然的出現了 spring-boot-starter-mail
. 無論怎麼說,每次的封裝都讓使用變得愈來愈簡單。html
建立 Springboot 項目不提,先看一下整體目錄結構。 java
直接引入 Springboot 郵件服務所需的依賴。git
<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郵箱爲例)、郵箱密碼以及編碼格式。github
spring.mail.host=smtp.126.com
spring.mail.port=25
# 你的郵箱地址
spring.mail.username=niumoo@126.com
# 你的受權碼(126 和 163 以及 qq 郵箱 都須要受權碼登陸,沒有受權碼的直接登陸網頁版郵箱設置裏設置)
spring.mail.password=password
spring.mail.default-encoding=UTF-8
複製代碼
文本郵件是最簡單也是最基礎的一種郵件,使用 Spring 封裝的 JavaMailSender
直接發送就能夠了。web
建立 MailService
類,注入 JavaMailSender
用於發送郵件,使用 @Value("${spring.mail.username}")
綁定配置文件中的參數用於設置郵件發送的來郵箱。使用 @Service
註解把 MailService
注入到 Spring 容器,使用 Lombok
的 @Slf4j
引入日誌。面試
/** * <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 的單元測試類測試文本郵件,實驗中的收信人爲了方便,都設置成了本身的郵箱。spring
@RunWith(SpringRunner.class)
@SpringBootTest
public class MailServiceTest {
@Autowired
private MailService mailService;
@Autowired
private TemplateEngine templateEngine;
@Test
public void sendSimpleTextMailTest() {
String to = "niumoo@126.com";
String subject = "Springboot 發送簡單文本郵件";
String content = "<p>第一封 Springboot 簡單文本郵件</p>";
mailService.sendSimpleTextMail(to, subject, content);
}
}
複製代碼
運行單元測試,測試文本郵件的發送。springboot
PS:若是運行報出異常 AuthenticationFailedException: 535 Error
. 通常都是用戶名和密碼有誤。app
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=niumoo@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 = "niumoo@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 = "niumoo@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 = "niumoo@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 = "niumoo@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 相關整合 - 郵件服務。
<完>
我的網站:www.codingme.net
若是你喜歡這篇文章,能夠關注公衆號,一塊兒成長。
關注公衆號回覆資源能夠沒有套路的獲取全網最火的的 Java 核心知識整理&面試資料。