在我們這個時代,郵件服務不管是對於工作上的交流,還是平時的各種郵件通知,都是一個十分重要的存在。Java 從很早時候就可以通過 Java mail 支持郵件服務。Spring 更是對 Java mail 進行了進一步的封裝,抽象出了 JavaMailSender
. 后來隨着 Springboot 的出現,理所當然的出現了 spring-boot-starter-mail
. 不管怎么說,每次的封裝都讓使用變得越來越簡單。
Springboot mail 依賴
創建 Springboot 項目不提,先看一下總體目錄結構。
直接引入 Springboot 郵件服務所需的依賴。
<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>
Springboot mail 配置
使用郵件服務需要配置自己可以使用的郵箱信息,一般需要配置發送協議 SMTP、郵箱帳號(本次以126郵箱為例)、郵箱密碼以及編碼格式。
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
Springboot mail 文本郵件
文本郵件是最簡單也是最基礎的一種郵件,使用 Spring 封裝的 JavaMailSender
直接發送就可以了。
創建 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 的單元測試類測試文本郵件,實驗中的收信人為了方便,都設置成了自己的郵箱。
@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);
}
}
運行單元測試,測試文本郵件的發送。
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 標簽也不會被解析。
Springboot mail 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 標簽也被解析成對應的樣式。
Springboot mail 附件郵件
在上面的 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);
}
運行單元測試,查看收信情況。
帶附件的郵件正常收到,多個附件的實現方式同理。
Springboot mail 圖片郵件
圖片郵件和其他的郵件方式略有不同,圖片郵件需要先在內容中定義好圖片的位置並出給一個記錄 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 mail 模版郵件
模版郵件的用處很廣泛,像經常收到的注冊成功郵件或者是操作通知郵件等都是模版郵件,模版郵件往往只需要更改其中的幾個變量。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 mail 補充
上面的例子中,是 Springboot 郵件服務的基本用法,代碼也有很多重復,和實際的使用情況相比還有很多不足,比如缺少異常處理機制
,在發送失敗時的重試機制
也沒有,實際情況中郵件服務往往對實時性不高,多說情況下會用於異步請求
。
文章相關代碼已經上傳 Github Spring Boot 相關整合 - 郵件服務。
我的微信:wn8398
原文出處: www.codingme.net