Spring Boot實戰系列(6)郵件傳送

五月君發表於2018-12-19

本篇主要介紹了Spring Boot中郵件傳送,分別講解了簡單的文字郵件、HTML郵件、附件郵件、圖片郵件、模板郵件。

快速導航

新增maven依賴

Spring Boot專案的pom.xml檔案中引入spring-boot-starter-email依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-email</artifactId>
    <scope>email</scope>
</dependency>
複製程式碼

模版郵件需要引入 spring-boot-starter-thymeleaf 外掛

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
複製程式碼

配置檔案增加郵箱相關配置

163郵箱配置,注意要替換自己的賬戶資訊,password為授權碼。

application.yml

spring: 
    mail:
        host: smtp.163.com
        username: your163account@163.com
        password: your163password
        default-encoding: utf-8
複製程式碼

QQ郵箱傳送郵件配置,以下password為授權碼

spring:
    mail:
        host: smtp.qq.com
        username: yourqqaccount@qq.com
        password: yourQQpassword
複製程式碼

專案構建

基於上節單元測試chapter5-1程式碼示例基礎之上編寫

業務層程式碼

service目錄下建立MailService.java檔案,負責業務層郵件傳送功能編寫

讓我們利用Spring提供的JavaMailSender介面實現郵件傳送,在專案中使用到地方用@Autowired注入郵件傳送物件

MailService.java

package com.angelo.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;

@Service
public class MailService {

    @Value("${spring.mail.username}")
    private String from;

    @Autowired // 專案啟動時將mailSender注入
    private JavaMailSender javaMailSender;

    // ... 下面會一一介紹 ...
}
複製程式碼

單元測試層程式碼

test測試目錄下建立MailServiceTest.java測試類,對業務層程式碼進行單元測試

MailServiceTest.java

package com.angelo.service;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.annotation.Resource;
import javax.mail.MessagingException;

import java.lang.reflect.Array;

import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
@SpringBootTest
public class MailServiceTest {

    @Autowired
    private MailService mailService;

    @Resource
    TemplateEngine templateEngine;

    String to = "your163password@163.com";

    // ... 下面為一一介紹 ...
}
複製程式碼

五種郵件傳送型別講解

文字郵件

SimpleMailMessage封裝了簡單郵件的傳送、接收功能、監測異常模組功能,這也是最簡單的一種郵件傳送,建立一個郵件訊息物件,設定郵件的傳送者、傳送物件、郵件主題、郵件內容。

  • 業務層MailService.java
/**
 * 傳送文字郵件
 * @param to
 * @param subject
 * @param content
 */
public void sendTextMail(String to, String subject, String content) {
    SimpleMailMessage message = new SimpleMailMessage();
    message.setTo(to); // 傳送物件
    message.setSubject(subject); // 郵件主題
    message.setText(content); // 郵件內容
    message.setFrom(from); // 郵件的發起者

    javaMailSender.send(message);
}
複製程式碼

對以上業務程式碼進行單元測試,檢視下效果

  • 單元測試層MailServiceTest.java
@Test
public void sendTextEmailTest() {
    mailService.sendTextMail(to, "傳送文字郵件", "hello,這是Spring Boot傳送的一封文字郵件!");
}
複製程式碼
  • 測試結果

圖片描述

html郵件

基於MimeMessageHelper建立helper物件,設定setText第二個引數為true,將會使用html格式列印郵件。

  • 業務層MailService.java
/**
 * 傳送HTMl郵件
 * @param to
 * @param subject
 * @param content
 * @throws MessagingException
 */
public void sendHtmlMail(String to, String subject, String content) throws MessagingException {
    MimeMessage message = javaMailSender.createMimeMessage();
    MimeMessageHelper helper = new MimeMessageHelper(message, true);
    helper.setFrom(from);
    helper.setTo(to);
    helper.setSubject(subject);
    helper.setText(content, true);

    javaMailSender.send(message);
}
複製程式碼
  • 單元測試層MailServiceTest.java
@Test
public void sendHtmlEmailTest() throws MessagingException {
    String content = "<html>" +
            "<body>" +
                "<h1 style=\"" + "color:red;" + "\">hello,這是Spring Boot傳送的一封HTML郵件</h1>" +
            "</body></html>";

    mailService.sendHtmlMail(to, "傳送HTML郵件", content);
}
複製程式碼
  • 測試結果

可以看到郵件結果使用了例子中預先設定好的郵件格式

圖片描述

附件郵件

  • 業務層MailService.java
    /**
     * 傳送帶附件的郵件
     * @param to
     * @param subject
     * @param content
     * @param filePathList
     * @throws MessagingException
     */
    public void sendAttachmentMail(String to, String subject, String content, String[] filePathList) throws MessagingException {
        MimeMessage message = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);

        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true);

        for (String filePath: filePathList) {
            System.out.println(filePath);

            FileSystemResource fileSystemResource = new FileSystemResource(new File(filePath));
            String fileName = fileSystemResource.getFilename();
            helper.addAttachment(fileName, fileSystemResource);
        }

        javaMailSender.send(message);
    }
複製程式碼

filePathList寫上你的附件檔案路徑,陣列格式。

  • 單元測試層MailServiceTest.java
    @Test
    public void sendAttachmentEmailTest() throws MessagingException {
        String[] filePathList = new String[2];
        filePathList[0] = "/SpringBoot-WebApi/chapter4.zip";
        filePathList[1] = "/SpringBoot-WebApi/chapter5.zip";

        mailService.sendAttachmentMail(to, "傳送附件郵件", "hello,這是Spring Boot傳送的一封附件郵件!", filePathList);
    }
複製程式碼
  • 測試結果

圖片描述

html內嵌圖片郵件

也是基於html郵件傳送,通過內嵌圖片等靜態資源,可以直接看到圖片。

  • 業務層MailService.java
    /**
     * 傳送html內嵌圖片的郵件
     * @param to
     * @param subject
     * @param content
     * @param srcPath
     * @param srcId
     * @throws MessagingException
     */
    public void sendHtmlInlinePhotoMail(String to, String subject, String content, String srcPath, String srcId) throws MessagingException {
        MimeMessage message = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);

        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true);

        FileSystemResource fileSystemResource = new FileSystemResource(new File(srcPath));
        helper.addInline(srcId, fileSystemResource);

        javaMailSender.send(message);
    }
複製程式碼

以下單元測試中srcPath為您的本地圖片路徑,srcId要和上面業務層的helper.addInline(srcId, fileSystemResource)srcId保持一致。

  • 單元測試層MailServiceTest.java
    @Test
    public void sendHtmlInlinePhotoMailTest() throws MessagingException {
        String srcPath = "/SpringBoot-WebApi/chapter6/img/pic18.jpg";
        String srcId = "pic18";
        String content = "<html>" +
                "<body>" +
                "<h2>hello,這是Spring Boot傳送的一封HTML內嵌圖片的郵件</h2>" +
                "<img src=\'cid:"+ srcId +"\'></img>" +
                "</body></html>";

        mailService.sendHtmlInlinePhotoMail(to, "傳送圖片郵件", content, srcPath, srcId);
    }
複製程式碼
  • 測試結果

圖片描述

模板郵件

郵件內容相對簡單的情況下,我們可以選擇使用以上幾種簡單郵件傳送方法,在複雜業務中需要用到html結構,且html裡的資料還需要動態修改,還是選擇模版郵件,可以使用Freemarkerthymeleaf等模板引擎,這裡主要介紹使用thymeleaf

  • 郵件模板編寫

resources/templates目錄下新建emailTemplate.html檔案

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>模板郵件</title>
</head>
<body>
您好,<span th:text="${username}"></span>,歡迎訪問我的個人部落格:
    <a href="https://github.com/Q-Angelo/summarize">Github</a><a th:href="@{https://www.imooc.com/u/{id}(id=${id})}" href="#">慕課網</a>
</body>
</html>
複製程式碼

利用上面介紹的傳送html郵件即可,在單元測試檔案中增加一個方法進行測試。

  • 單元測試層MailServiceTest.java
@Test
public void testTemplateEmailTest() throws MessagingException {
    Context context = new Context();
    context.setVariable("username", "張三");
    context.setVariable("id", "2667395");

    String emailContent = templateEngine.process("emailTemplate", context);

    mailService.sendHtmlMail(to, "傳送模板郵件", emailContent);
}
複製程式碼
  • 測試結果

圖片描述

常見問題

出現這個錯誤的原因是網易將我傳送的郵件當成了垃圾郵件,<<傳送163文字郵件>>這是我填寫的郵件標題,後來發現網易是對標題裡面含了163導致的,大家遇到類似問題多檢查下。

com.sun.mail.smtp.SMTPSendFailedException: 554 DT:SPM 163 smtp10,DsCowADH1MxWegtcyxFjDw--.48939S2 1544256086
複製程式碼

如遇到什麼問題可在下方評論區提問

Github檢視本文完整示例 chapter6-1

作者:五月君
連結:www.imooc.com/article/267…
來源:慕課網
Github: Spring Boot實戰系列

相關文章