Springboot 系列(十三)使用郵件服務

在咱們這個時代,郵件服務不論是對於工做上的交流,仍是平時的各類郵件通知,都是一個十分重要的存在。Java 從很早時候就能夠經過 Java mail 支持郵件服務。Spring 更是對 Java mail 進行了進一步的封裝,抽象出了 JavaMailSender. 後來隨着 Springboot 的出現,理所固然的出現了 spring-boot-starter-mail. 無論怎麼說,每次的封裝都讓使用變得愈來愈簡單。html

<!-- more -->java

Springboot mail 依賴

建立 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>

Springboot mail 配置

使用郵件服務須要配置本身可使用的郵箱信息,通常須要配置發送協議 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

Springboot mail 文本郵件

文本郵件是最簡單也是最基礎的一種郵件,使用 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 標籤也不會被解析。

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 相關整合 - 郵件服務

<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>

相關文章
相關標籤/搜索