Spring Boot-實現郵件發送

相信使用過Spring的衆多開發者都知道Spring提供了很是好用的JavaMailSender接口實現郵件發送,在Spring Boot的Starter模塊中也爲此提供了自動化配置,下面經過實例看看如何在Spring Boot中使用JavaMailSender發送郵件,本文以@163.com郵箱爲例闡述。html


What-什麼是郵件服務

郵件服務在互聯網早期就已經出現,現在已成爲人們互聯網生活中必不可少的一項服務。那麼郵件服務是怎麼工做的呢?以下給出郵件發送與接收的典型過程:
一、發件人使用SMTP協議傳輸郵件到郵件服務器A;
二、郵件服務器A根據郵件中指定的接收者,投送郵件至相應的郵件服務器B;
三、收件人使用POP3協議從郵件服務器B接收郵件。
SMTP(Simple Mail Transfer Protocol)是電子郵件(email)傳輸的互聯網標準,定義在RFC5321,默認使用端口25;
POP3(Post Office Protocol - Version 3)主要用於支持使用客戶端遠程管理在服務器上的電子郵件。定義在RFC 1939,爲POP協議的第三版(最新版)。
這兩個協議均屬於TCP/IP協議族的應用層協議,運行在TCP層之上。
咱們平常收發郵件使用的客戶端、Web Mail的背後都在運行着這兩個協議,完成收發郵件的過程。而如今咱們須要使用SMTP協議來把發送給用戶的郵件傳輸到郵件服務器。
從客戶端傳輸郵件到服務器須要雙方的配合,而規則就定義在SMTP協議中。咱們如今須要作的是找一個SMTP服務器,再實現一個SMTP客戶端,而後讓客戶端發送郵件到服務器。java


Why-爲何系統要創建郵件服務

電子郵件具備全世界通用的協議。因此你可使用任何一種郵件的客戶端,以任何一種方式去查看你的郵件。這個世界上的電子郵件客戶端不下千種,他們都以不一樣的方式去知足了不一樣需求的人羣,郵件有如下特色:
① 企業內部的溝通,郵件服務仍是被認爲「正式」的,比即時通訊「可靠」。
② 支持轉發/抄送,公開的,統一的通訊協議,可以存檔。spring


Why-如何實現郵件服務

  • 配置郵件服務器

開啓SMTP服務器,設置受權碼,後續編寫代碼須要改受權碼,編碼中的密碼非郵箱登陸密碼而是受權碼,如:設置受權碼爲:123456。
圖片描述json


  • 實現郵件客戶端

① Gradle添加Spring Mail依賴服務器

compile group: 'org.springframework.boot', name: 'spring-boot-starter-mail'

② 修改application.properties,添加郵箱配置app

##################################---Spring Mail發送郵件---##############################################
# JavaMailSender 郵件發送的配置
spring.mail.default-encoding=UTF-8 
spring.mail.host=smtp.163.com
spring.mail.port=465
spring.mail.username=javalsj@163.com
# 郵箱開啓的受權碼
spring.mail.password=123456
spring.mail.properties.smtp.auth=true
spring.mail.properties.smtp.starttls.enable=true
spring.mail.properties.smtp.starttls.required=true
spring.mail.properties.mail.smtp.ssl.enable=true

  • 編寫發送郵件工具JavaMailUtil代碼,支持發送純文本郵件、html郵件、附件郵件、thymeleaf模板郵件類型。
package com.javalsj.blog.mail;

import java.io.File;
import java.util.Map;

import javax.mail.internet.MimeMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import com.javalsj.blog.common.FileUtil;

/**
 * @description 發送郵件工具,支持發送純文本郵件、html郵件、附件郵件、thymeleaf模板郵件類型。
 * @author WANGJIHONG
 * @date 2018年3月14日 下午10:17:40
 * @Copyright 版權全部 (c) www.javalsj.com
 * @memo 無備註說明
 */
@Component
public class JavaMailUtil {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * Java郵件發送器
     */
    @Autowired
    private JavaMailSender mailSender;

    /**
     * thymeleaf模板引擎
     */
    @Autowired
    private TemplateEngine templateEngine;

    /**
     * 發送不含附件,且不含嵌入html靜態資源頁面的純文本簡單郵件
     * 
     * @param deliver
     *            發送人郵箱名 如: javalsj@163.com
     * @param receiver
     *            收件人,可多個收件人 如:11111@qq.com,2222@163.com
     * @param carbonCopy
     *            抄送人,可多個抄送人 如:33333@sohu.com
     * @param subject
     *            郵件主題 如:您收到一封高大上的郵件,請查收。
     * @param text
     *            郵件內容 如:測試郵件逗你玩的。
     */
    public void sendSimpleEmail(String deliver, String[] receivers, String[] carbonCopys, String subject, String text)
            throws Exception {
        sendMimeMail(deliver, receivers, carbonCopys, subject, text, false, null);
    }

    /**
     * 發送含嵌入html靜態資源頁面, 但不含附件的郵件
     * 
     * @param deliver
     *            發送人郵箱名 如: javalsj@163.com
     * @param receivers
     *            收件人,可多個收件人 如:11111@qq.com,2222@163.com
     * @param carbonCopys
     *            抄送人,可多個抄送人 如:3333@sohu.com
     * @param subject
     *            郵件主題 如:您收到一封高大上的郵件,請查收。
     * @param text
     *            郵件內容 如: <html><body>
     *            <h1>213123</h1></body></html>
     */
    public void sendHtmlEmail(String deliver, String[] receivers, String[] carbonCopys, String subject, String text)
            throws Exception {
        sendMimeMail(deliver, receivers, carbonCopys, subject, text, true, null);
    }

    /**
     * 發送含附件,但不含嵌入html靜態資源頁面的郵件
     * 
     * @param deliver
     *            發送人郵箱名 如: javalsj@163.com
     * @param receivers
     *            收件人,可多個收件人 如:11111@qq.com,2222@163.com
     * @param carbonCopys
     *            抄送人,可多個抄送人 如:3333@sohu.com.cn
     * @param subject
     *            郵件主題 如:您收到一封高大上的郵件,請查收。
     * @param text
     *            郵件內容 如:測試郵件逗你玩的。
     * @param attachmentFilePaths
     *            附件文件路徑 如:http://www.javalsj.com/resource/test.jpg,
     *            http://www.javalsj.com/resource/test2.jpg
     */
    public void sendAttachmentsEmail(String deliver, String[] receivers, String[] carbonCopys, String subject,
            String text, String[] attachmentFilePaths) throws Exception {
        sendMimeMail(deliver, receivers, carbonCopys, subject, text, false, attachmentFilePaths);
    }

    /**
     * 發送含附件,且含嵌入html靜態資源頁面的郵件
     * 
     * @param deliver
     *            發送人郵箱名 如: javalsj@163.com
     * @param receivers
     *            收件人,可多個收件人 如:11111@qq.com,2222@163.com
     * @param carbonCopys
     *            抄送人,可多個抄送人 如:33333@jiuqi.com.cn
     * @param subject
     *            郵件主題 如:您收到一封高大上的郵件,請查收。
     * @param text
     *            <html><body><img src=\"cid:test\"><img
     *            src=\"cid:test2\"></body></html>
     * @param attachmentFilePaths
     *            附件文件路徑 如:http://www.javalsj.com/resource/test.jpg,
     *            http://www.javalsj.com/resource/test2.jpg
     *            須要注意的是addInline函數中資源名稱attchmentFileName須要與正文中cid:attchmentFileName對應起來
     */
    public void sendHtmlAndAttachmentsEmail(String deliver, String[] receivers, String[] carbonCopys, String subject,
            String text, String[] attachmentFilePaths) throws Exception {
        sendMimeMail(deliver, receivers, carbonCopys, subject, text, true, attachmentFilePaths);
    }

    /**
     * 發送thymeleaf模板郵件
     * 
     * @param deliver
     *            發送人郵箱名 如: javalsj@163.com
     * @param receivers
     *            收件人,可多個收件人 如:11111@qq.com,2222@163.com
     * @param carbonCopys
     *            抄送人,可多個抄送人 如:33333@sohu.com
     * @param subject
     *            郵件主題 如:您收到一封高大上的郵件,請查收。
     * @param thymeleafTemplatePath
     *            郵件模板 如:mail\mailTemplate.html。
     * @param thymeleafTemplateVariable
     *            郵件模板變量集 
     */
    public void sendTemplateEmail(String deliver, String[] receivers, String[] carbonCopys, String subject, String thymeleafTemplatePath,
            Map<String, Object> thymeleafTemplateVariable) throws Exception {
        String text = null;
        if (thymeleafTemplateVariable != null && thymeleafTemplateVariable.size() > 0) {
            Context context = new Context();
            thymeleafTemplateVariable.forEach((key, value)->context.setVariable(key, value));
            text = templateEngine.process(thymeleafTemplatePath, context);
        }
        sendMimeMail(deliver, receivers, carbonCopys, subject, text, true, null);
    }

    /**
     * 發送的郵件(支持帶附件/html類型的郵件)
     * 
     * @param deliver
     *            發送人郵箱名 如: javalsj@163.com
     * @param receivers
     *            收件人,可多個收件人 如:11111@qq.com,2222@163.com
     * @param carbonCopys
     *            抄送人,可多個抄送人 如:3333@sohu.com
     * @param subject
     *            郵件主題 如:您收到一封高大上的郵件,請查收。
     * @param text
     *            郵件內容 如:測試郵件逗你玩的。 <html><body><img
     *            src=\"cid:attchmentFileName\"></body></html>
     * @param attachmentFilePaths
     *            附件文件路徑 如:
     *            須要注意的是addInline函數中資源名稱attchmentFileName須要與正文中cid:attchmentFileName對應起來
     * @throws Exception
     *             郵件發送過程當中的異常信息
     */
    private void sendMimeMail(String deliver, String[] receivers, String[] carbonCopys, String subject, String text,
            boolean isHtml, String[] attachmentFilePaths) throws Exception {
        StopWatch stopWatch = new StopWatch();
        try {
            stopWatch.start();
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom(deliver);
            helper.setTo(receivers);
            helper.setCc(carbonCopys);
            helper.setSubject(subject);
            helper.setText(text, isHtml);
            // 添加郵件附件
            if (attachmentFilePaths != null && attachmentFilePaths.length > 0) {
                for (String attachmentFilePath : attachmentFilePaths) {
                    File file = new File(attachmentFilePath);
                    if (file.exists()) {
                        String attachmentFile = attachmentFilePath
                                .substring(attachmentFilePath.lastIndexOf(File.separator));
                        long size = FileUtil.getDirSize(file);
                        if (size > 1024 * 1024) {
                            String msg = String.format("郵件單個附件大小不容許超過1MB,[%s]文件大小[%s]。", attachmentFilePath,
                                    FileUtil.formatSize(size));
                            throw new RuntimeException(msg);
                        } else {
                            FileSystemResource fileSystemResource = new FileSystemResource(file);
                            helper.addInline(attachmentFile, fileSystemResource);
                        }
                    }
                }
            }
            mailSender.send(mimeMessage);
            stopWatch.stop();
            logger.info("郵件發送成功, 花費時間{}秒", stopWatch.getTotalTimeSeconds());
        } catch (Exception e) {
            logger.error("郵件發送失敗, 失敗緣由 :{} 。", e.getMessage(), e);
            throw e;
        }
    }

}

  • 編寫簡單文本郵件發送控制器
@RequestMapping(value = "/sendSimpleEmail", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Result sendSimpleEmail() {
        Result result;
        try {
            javaMailUtil.sendSimpleEmail("javalsj@163.com", new String[] { "1111@qq.com", "2222@qq.com" },
                    new String[] { "33333@sohu.com" }, "您收到一封高大上的郵件,請查收。", "測試郵件逗你玩的。");
            result = ResultFactory.buildSuccessResult(null);
        } catch (Exception e) {
            result = ResultFactory.buildFailResult(e.getMessage());
        }
        return result;
    }

效果以下:
圖片描述函數


  • 編寫模板引擎頁面郵件發送

圖片描述

mailTemplate.html頁面代碼:spring-boot

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
    xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>郵件模板</title>
</head>
<body>
    <div>
        用戶名:<input th:text="${username}"/> <br /> 
        密碼: <input th:text="${password}"/>
    </div>
</body>
</html>

控制器測試代碼:工具

@RequestMapping(value = "/sendTemplateEmail", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Result sendTemplateEmail() {
        Result result = null;
        try {
            String thymeleafTemplatePath = "mail/mailTemplate";
            Map<String, Object> thymeleafTemplateVariable = new HashMap<String, Object>();
            thymeleafTemplateVariable.put("username", "javalsj");
            thymeleafTemplateVariable.put("password", "123456");
            javaMailUtil.sendTemplateEmail("javalsj@163.com", 
                    new String[] { "11111@qq.com", "22222@qq.com" },
                    new String[] { "3333@sohu.com" }, 
                    "您收到一封高大上的郵件,請查收。",
                    thymeleafTemplatePath,
                    thymeleafTemplateVariable);
            result = ResultFactory.buildSuccessResult(null);
        } catch (Exception e) {
            result = ResultFactory.buildFailResult(e.getMessage());
        }
        return result;
    }

效果以下:
圖片描述測試


總結

本文使用Spring Boot + JavaMailSender + Thymeleaf實現了服務端發送純文本郵件、html郵件、附件郵件以及Thymeleaf模板郵件功能,因爲Spring Boot默認模板引擎爲Thymeleaf,因此使用默認的Thymeleaf自動配置便可,本文未作Thymeleaf的單獨配置。

相關文章
相關標籤/搜索