首頁 > 軟體

SpringBoot實現定時傳送郵件的三種方法案例詳解

2023-03-07 06:01:33

一、傳送郵件的三種方法

1、傳送純文字郵件

2、傳送複雜郵件

3、傳送模板郵件

二、定時任務介紹

Spring框架的定時任務排程功能支援設定和註解兩種方式Spring Boot在Spring框架的基礎上實現了繼承,並對其中基於註解方式的定時任務實現了非常好的支援。下面,針對 Spring Boot 專案中基於註解方式的定時任務排程的相關注解和使用進行介紹。

1.@EnableScheduling

@EnableScheduling 註解是 Spring 框架提供的,用於開啟基於註解方式的定時任務支援,該註解主要用在專案啟動類上。

2.@Scheduled

@Scheduled 註解同樣是 Spring 框架提供的,設定定時任務的執行規則,該註解主要用在定時業務方法上。@Scheduled 註解提供有多個屬性,精細化設定定時任務執行規則

屬性說明
cron類似於 cron 的表示式,可以客製化定時任務觸發的秒、分鐘、小時、月中的日、月、週中的日
zone表示在上一次任務執行結束後在指定時間後繼續執行下一次任務(屬性值為long型別)
fixedDelay指定cron 表示式將被解析的時區。預設情況下,該屬性是空字串(即使用伺服器的本地時區
fixedDelayString表示在上一次任務執行結束後在指定時間後繼續執行下一次任務(屬性值為long型別的字串形式)
fixedRate表示每隔指定時間執行一次任務 (屬性值為 long 型別)
fixedRateString表示每隔指定時間執行一次任務(屬性值為 long 型別的字串形式)
initialDelay表示在fixedRate 或fixedDelay 任務第一次執行之前要延遲的毫秒數(屬性值為long型別)
initialDelayString表示在fixedRate或fixedDelay 任務第一次執行之前要延遲的毫秒數(屬性值為long型別的字串形式)

三、前期準備工作

1、登入QQ郵箱獲取授權碼

第一步:進入QQ郵箱

第二步:找到POP3/SMTP,並開啟

第三步:複製授權碼

開啟過程需要手機號碼驗證,按照步驟操作即可。開啟成功之後,即可獲取一個授權碼,將該號碼儲存好,一會使用

2、pom.xml中的依賴

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</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>
        <!--新增下面的依賴後,Spring Boot自動設定的郵件服務會生效,在郵件傳送任務時,
            可以直接使用Spring框架提供的JavaMailSender介面或者它的實現類JavaMailSenderImpl郵件        
        傳送-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
    </dependencies>

3、在全域性組態檔application.properties新增郵件服務設定

# 發件人郵件伺服器相關設定
spring.mail.host=smtp.qq.com
spring.mail.port=587
# 設定個人QQ賬戶和密碼(這裡需要大家修改為自己的QQ賬號和密碼,密碼是加密後的授權碼,授權碼的獲得後繼講解)
spring.mail.username=QQ@qq.com
spring.mail.password=填入剛剛複製的授權碼
spring.mail.default-encoding=UTF-8
# 郵件服務超時時間設定
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=3000
spring.mail.properties.mail.smtp.writetimeout=5000

四、操作

一、建立郵件傳送任務管理的業務處理類SendEmailService

注意:在方法上的註解@Async是需要搭配定時任務一起使用的,如果使用普通的test類時可以不用這個註解的

package com.lyn.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.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
 
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
 
/**
 * @author:Lyn.R
 * @date:2023-02-21 14:54:36
 * @Description:
 * @note:
 **/
@Service
public class SendEmailService {
    @Autowired
    private JavaMailSenderImpl mailSender;//使用Spring框架提供的實現類JavaMailSenderImpl來實現郵件傳送。
    @Value("${spring.mail.username}")//藉助@Value註解讀取全域性變數中的spring.mail.username的值來作發件人
    private String from;
    /**
     * 第一種方法:傳送純文字郵件
     * @param to      收件人地址
     * @param subject 郵件標題
     * @param text    郵件內容
     */
   @Async
    public void sendSimpleEmail(String to, String subject, String text) {
        // 客製化純文字郵件資訊SimpleMailMessage
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);//設定發件人
        message.setTo(to);//設定收件人
        message.setSubject(subject);//設定郵件標題
        message.setText(text);//設定 正檔案內容
        try {
            // 傳送郵件
            mailSender.send(message);
            System.out.println("純文字郵件傳送成功");
        } catch (MailException e) {
            System.out.println("純文字郵件傳送失敗 " + e.getMessage());
            e.printStackTrace();
        }
    }
    /**
     * 第二種方法:傳送複雜郵件(包括靜態資源和附件)
     * @param to           收件人地址
     * @param subject      郵件標題
     * @param text         郵件內容
     * @param filePath     附件地址
     * @param rscId        靜態資源唯一標識
     * @param rscPath      靜態資源地址
     */
    //sendComplexEmail()方法需要接收的引數除了基本的傳送資訊外,還包括靜態資源唯一標識、靜態資源路徑和附件路徑
    @Async
    public void sendComplexEmail(String to,String subject,String text,String filePath,String rscId,String rscPath){
        // 客製化複雜郵件資訊MimeMessage
        MimeMessage message = mailSender.createMimeMessage();
        try {
            // 使用MimeMessageHelper幫助類對郵件資訊封裝處理 ,並設定multipart多部件使用為true
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(text, true);
            // 設定郵件靜態資源
            FileSystemResource res = new FileSystemResource(new File(rscPath));
            helper.addInline(rscId, res);//設定郵件靜態資源的方法
            // 設定郵件附件
            FileSystemResource file = new FileSystemResource(new File(filePath));
            String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
            helper.addAttachment(fileName, file);//設定郵件附件的方法
            // 傳送郵件
            mailSender.send(message);
            System.out.println("複雜郵件傳送成功");
        } catch (MessagingException e) {
            System.out.println("複雜郵件傳送失敗 "+e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 第三鍾方法:傳送模板郵件
     * @param to       收件人地址
     * @param subject  郵件標題
     * @param content  郵件內容
     */
    @Async
    public void sendTemplateEmail(String to, String subject, String content) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            // 使用MimeMessageHelper幫助類對郵件資訊進行封裝處理,並設定multipart多部件使用為true
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);
            // 傳送郵件
            mailSender.send(message);
            System.out.println("模板郵件傳送成功");
        } catch (MessagingException e) {
            System.out.println("模板郵件傳送失敗 "+e.getMessage());
            e.printStackTrace();
        }
    }
 
}

二、在test類中傳送郵件

package com.lyn;
 
import com.lyn.service.SendEmailService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
 
@SpringBootTest
class SpringbootHomeworkEmail0221ApplicationTests {
 
    @Autowired
    private SendEmailService sendEmailService;
    @Test
    public void sendSimpleMailTest() {
        String to="12345678@qq.com";//這裡修改為你能接收到的郵箱
        String subject="【純文字郵件】標題";
        String text="嘟嘟嘟.....";
        // 傳送簡單郵件
        sendEmailService.sendSimpleEmail(to,subject,text);
    }
    @Test
    public void sendComplexEmailTest() {
        //根據前面定義的複雜郵件傳送業務客製化各種引數
        String to="12345678@qq.com";//修改為你自己的郵件方便接收檢視
        String subject="【複雜郵件】標題";
        // 定義郵件內容
        StringBuilder text = new StringBuilder();
        //對郵件內容使用了HTML標籤編輯郵件內容
        text.append("<html><head></head>");
        text.append("<body><h1>二月二龍擡頭!</h1>");
        // cid為嵌入靜態資原始檔關鍵字的固定寫法,如果改變將無法識別;rscId則屬於自定義的靜態資源唯一標識,一個郵件內容中可能會包括多個靜態資源,該屬性是為了區別唯一性的。
        String rscId = "img001";
        text.append("<img src='cid:" +rscId+"'/></body>");
        text.append("</html>");
        // 指定靜態資原始檔和附件路徑
        String rscPath="D:\1.jpg";//注意這裡修改為你的硬碟中有的資源
        String filePath="D:\hahaha.txt";//注意這裡修改為你的硬碟中有的資源
        // 傳送複雜郵件
        sendEmailService.sendComplexEmail(to,subject,text.toString(),filePath,rscId,rscPath);
    }
 
    @Autowired
    private TemplateEngine templateEngine;
    @Test
    public void sendTemplateEmailTest() {
        String to="12345678@qq.com";
        String subject="【模板郵件】標題";
        // 使用模板郵件客製化郵件正文內容
        Context context = new Context();//Context注意正確匯入「import org.thymeleaf.context.Context;」
        context.setVariable("username", "石頭");
        context.setVariable("code", "456123");
        // 使用TemplateEngine設定要處理的模板頁面
        String emailContent = templateEngine.process("emailTemplate_vercode", context);
        // 傳送模板郵件
        sendEmailService.sendTemplateEmail(to,subject,emailContent);
    }
}

模板檔案的html(emailTemplate_vercode.html)

<!DOCTYPE html>
<html lang="en">
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>使用者驗證碼</title>
</head>
<body>
<div><span th:text="${username}">XXX</span>&nbsp;先生/女士,您好:</div>
<P style="text-indent: 2em">您的新使用者驗證碼為<span th:text="$[code]" style="color: cornflowerblue">123456</span>,請妥善保管。</P>
</body>
</html>

三、傳送定時郵件

下面類中的 @Scheduled(cron = "*/5 * * * * ?")表示式大家可以去下面的網址生成Cron - 線上Cron表示式生成器 (ciding.cc)

package com.lyn.controller;
 
import com.lyn.service.SendEmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
 
/**
 * @author:Lyn.R
 * @date:2023-02-21 19:55:01
 * @Description:
 * @note:
 **/
@Controller
public class MyScheduled {
    @Autowired
    private SendEmailService sendEmailService;
 
    @Autowired
    //模板引擎(Template Engine), 是用來解析對應型別模板檔案然後動態生成由資料和靜態頁面組成的檢視檔案的一個工具
    private TemplateEngine templateEngine;
 
    @Scheduled(cron = "*/5 * * * * ?")
    public void sendSimpleMailTest() {
        String to="12345678@qq.com";//這裡修改為你能接收到的郵箱
        String subject="【純文字郵件】標題";
        String text="嘟嘟嘟.....";
        // 傳送簡單郵件
        sendEmailService.sendSimpleEmail(to,subject,text);
    }
    @Scheduled(cron = "1 * * * * ?  ")
    public void sendComplexEmailTest() {
        //根據前面定義的複雜郵件傳送業務客製化各種引數
        String to="12345678@qq.com";//修改為你自己的郵件方便接收檢視
        String subject="【複雜郵件】標題";
        // 定義郵件內容
        StringBuilder text = new StringBuilder();
        //對郵件內容使用了HTML標籤編輯郵件內容
        text.append("<html><head></head>");
        text.append("<body><h1>二月二龍擡頭!</h1>");
        // cid為嵌入靜態資原始檔關鍵字的固定寫法,如果改變將無法識別;rscId則屬於自定義的靜態資源唯一標識,一個郵件內容中可能會包括多個靜態資源,該屬性是為了區別唯一性的。
        String rscId = "img001";
        text.append("<img src='cid:" +rscId+"'/></body>");
        text.append("</html>");
        // 指定靜態資原始檔和附件路徑
        String rscPath="D:\1.jpg";//注意這裡修改為你的硬碟中有的資源
        String filePath="D:\hahaha.txt";//注意這裡修改為你的硬碟中有的資源
        // 傳送複雜郵件
        sendEmailService.sendComplexEmail(to,subject,text.toString(),filePath,rscId,rscPath);
    }
 
    @Scheduled(cron = "0 * * * * ? ")
    public void sendTemplateEmailTest() {
        String to="12345678@qq.com";
        String subject="【模板郵件】標題";
        // 使用模板郵件客製化郵件正文內容
        Context context = new Context();//Context注意正確匯入「import org.thymeleaf.context.Context;」
        context.setVariable("username", "石頭");
        context.setVariable("code", "456123");
        // 使用TemplateEngine設定要處理的模板頁面
        String emailContent = templateEngine.process("emailTemplate_vercode", context);
        // 傳送模板郵件
        sendEmailService.sendTemplateEmail(to,subject,emailContent);
    }
}

四、在專案啟動類上新增基於註解的定時任務支援:@EnableScheduling

package com.lyn;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
 
@SpringBootApplication
@EnableScheduling
public class SpringbootHomeworkEmail0221Application {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringbootHomeworkEmail0221Application.class, args);
    }
 
}

注意:郵件發多了,可能會導致qq郵箱認為是垃圾郵件,就會出現報錯,所以儘量不要進行郵箱轟炸

到此這篇關於SpringBoot三種方法實現定時傳送郵件的案例的文章就介紹到這了,更多相關SpringBoot定時傳送郵件內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com