欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

重學(xué)SpringBoot3之如何發(fā)送Email郵件功能

 更新時(shí)間:2024年11月22日 09:23:44   作者:CoderJia_  
這篇文章主要給大家介紹了重學(xué)SpringBoot3之如何發(fā)送Email郵件功能的相關(guān)資料,文中包括環(huán)境準(zhǔn)備、項(xiàng)目配置、代碼實(shí)現(xiàn)、最佳實(shí)踐和安全性建議,通過采用異步發(fā)送、重試機(jī)制、限流等最佳實(shí)踐,可以構(gòu)建一個(gè)健壯的郵件發(fā)送系統(tǒng),需要的朋友可以參考下

前言

在企業(yè)應(yīng)用開發(fā)中,發(fā)送郵件是一個(gè)非常常見的需求,比如用戶注冊(cè)驗(yàn)證、密碼重置、系統(tǒng)通知等場(chǎng)景。SpringBoot 3提供了完善的郵件發(fā)送支持,本文將詳細(xì)介紹如何在SpringBoot 3中實(shí)現(xiàn)郵件發(fā)送功能,并提供最佳實(shí)踐建議。

1. 環(huán)境準(zhǔn)備

  • JDK 17+
  • SpringBoot 3.0+
  • Maven/Gradle

2. 項(xiàng)目配置

2.1 添加依賴

在 pom.xml中添加以下依賴:

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

2.2 配置郵件服務(wù)器

在 application.yml中添加郵件服務(wù)器配置:

spring:
  mail:
    host: smtp.qq.com  # QQ郵件服務(wù)器地址
    port: 587            # 端口號(hào)
    username: ${username}
    password: ${password}  # 需要去QQ郵箱開通開通POP3/IMAP服務(wù),并設(shè)置專用密碼
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true
            required: true
  thymeleaf:
    cache: true
    check-template: true
    check-template-location: true
    content-type: text/html
    enabled: true
    encoding: UTF-8
    excluded-view-names: ''
    mode: HTML
    prefix: classpath:/templates/
    suffix: .html

3. 代碼實(shí)現(xiàn)

3.1 創(chuàng)建郵件服務(wù)接口

package com.example.springboot3email.service;

import org.springframework.web.multipart.MultipartFile;

/**
 * @author CoderJia
 * @create 2024/11/21 10:22
 * @Description
 **/
public interface IEmailService {

    void sendSimpleEmail(String to, String subject, String text);

    void sendHtmlEmail(String to, String subject, String htmlContent);

    void sendEmailWithAttachment(String to, String subject, String text, MultipartFile attachment);
}

3.2 實(shí)現(xiàn)郵件服務(wù)

package com.example.springboot3email.service;

import jakarta.annotation.Resource;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;
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 org.springframework.web.multipart.MultipartFile;

import java.io.File;

/**
 * @author CoderJia
 * @create 2024/11/21 10:23
 * @Description
 **/
@Service
@Slf4j
public class EmailServiceImpl implements IEmailService {

    @Resource
    private JavaMailSender mailSender;

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

    /**
     * 發(fā)送簡(jiǎn)單文本郵件
     *
     * @param to
     * @param subject
     * @param text
     */
    @Override
    public void sendSimpleEmail(String to, String subject, String text) {
        try {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(from);
            message.setTo(to);
            message.setSubject(subject);
            message.setText(text);

            mailSender.send(message);
            log.info("Simple email sent successfully to: {}", to);
        } catch (Exception e) {
            log.error("Failed to send simple email", e);
            throw new RuntimeException("Failed to send email", e);
        }
    }

    /**
     * 發(fā)送HTML格式的郵件
     *
     * @param to
     * @param subject
     * @param htmlContent
     */
    @Override
    public void sendHtmlEmail(String to, String subject, String htmlContent) {
        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

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

            mailSender.send(message);
            log.info("HTML email sent successfully to: {}", to);
        } catch (Exception e) {
            log.error("Failed to send HTML email", e);
            throw new RuntimeException("Failed to send email", e);
        }
    }

    /**
     * 發(fā)送帶附件的郵件
     *
     * @param to
     * @param subject
     * @param text
     * @param attachment
     */
    @Override
    public void sendEmailWithAttachment(String to, String subject, String text, MultipartFile attachment) {
        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(text);

            // 創(chuàng)建臨時(shí)文件
            File tempFile = File.createTempFile("upload_", attachment.getOriginalFilename());
            attachment.transferTo(tempFile);

            // 使用 FileSystemResource 包裝臨時(shí)文件
            FileSystemResource file = new FileSystemResource(tempFile);
            helper.addAttachment(attachment.getOriginalFilename(), file);

            mailSender.send(message);
            log.info("Email with attachment sent successfully to: {}", to);

            // 刪除臨時(shí)文件
            tempFile.delete();
        } catch (Exception e) {
            log.error("Failed to send email with attachment", e);
            throw new RuntimeException("Failed to send email", e);
        }
    }
}

3.3 創(chuàng)建郵件模板

在 resources/templates目錄下創(chuàng)建HTML模板 EmailTemplate.html(使用Thymeleaf):

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Email Template</title>
</head>
<body>
    <h1>Welcome, <span th:text="${name}">User</span>!</h1>
    <p>This is a sample email template using Thymeleaf.</p>
    <p>Your verification code is: <strong th:text="$[code]">123456</strong></p>
</body>
</html>

3.4 使用模板發(fā)送郵件

@Service
public class TemplateEmailService {
  
    @Autowired
    private EmailService emailService;
  
    @Autowired
    private TemplateEngine templateEngine;
  
    public void sendTemplateEmail(String to, String subject, String templateName, Map<String, Object> variables) {
        Context context = new Context();
        variables.forEach(context::setVariable);
      
        String htmlContent = templateEngine.process(templateName, context);
        emailService.sendHtmlEmail(to, subject, htmlContent);
    }
}

4. 最佳實(shí)踐建議

4.1 異步發(fā)送

為避免郵件發(fā)送影響主業(yè)務(wù)流程,建議使用異步方式發(fā)送郵件:

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
  
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.setThreadNamePrefix("EmailAsync-");
        executor.initialize();
        return executor;
    }
}

@Service
public class AsyncEmailService {
  
    @Async
    public CompletableFuture<Void> sendEmailAsync(String to, String subject, String content) {
        // 郵件發(fā)送邏輯

        return CompletableFuture.completedFuture(null);
    }
}

4.2 重試機(jī)制

實(shí)現(xiàn)郵件發(fā)送重試機(jī)制:

@Service
public class RetryableEmailService {
  
    @Retryable(value = {MessagingException.class}, 
               maxAttempts = 3,
               backoff = @Backoff(delay = 1000))
    public void sendEmailWithRetry(String to, String subject, String content) {
        // 郵件發(fā)送邏輯
    }
  
    @Recover
    public void recover(MessagingException e, String to) {
        // 處理最終失敗的情況
        log.error("Failed to send email after retries", e);
    }
}

4.3 郵件發(fā)送限流

使用令牌桶算法實(shí)現(xiàn)郵件發(fā)送限流:

@Service
public class RateLimitedEmailService {
  
    private final RateLimiter rateLimiter = RateLimiter.create(10.0); // 每秒10封郵件
  
    public void sendEmailWithRateLimit(String to, String subject, String content) {
        if (rateLimiter.tryAcquire()) {
            // 發(fā)送郵件
        } else {
            throw new RuntimeException("Rate limit exceeded");
        }
    }
}

4.4 郵件發(fā)送記錄

記錄郵件發(fā)送歷史:

@Entity
@Table(name = "email_log")
public class EmailLog {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
  
    private String to;
    private String subject;
    private LocalDateTime sendTime;
    private EmailStatus status;
    private String errorMessage;
  
    // getters and setters
}

5. 安全性建議

  • 不要在代碼中硬編碼郵件服務(wù)器憑證
  • 使用環(huán)境變量或配置中心存儲(chǔ)敏感信息
  • 實(shí)現(xiàn)郵件發(fā)送頻率限制,防止濫用
  • 記錄郵件發(fā)送日志,便于問題排查
  • 使用TLS/SSL加密傳輸
  • 定期輪換郵件服務(wù)器密碼

6. 測(cè)試示例

package com.example.springboot3email.controller;

import com.example.springboot3email.service.IEmailService;
import com.example.springboot3email.service.TemplateEmailService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

/**
 * @author CoderJia
 * @create 2024/11/21 10:32
 * @Description
 **/
@Slf4j
@RestController
public class EmailController {
    @Resource
    private IEmailService emailService;

    @Resource
    private TemplateEmailService templateEmailService;


    // 發(fā)送簡(jiǎn)單文本郵件接口
    @PostMapping("/sendSimpleEmail")
    public String sendSimpleEmail(@RequestParam("to") String to,
                                  @RequestParam("subject") String subject,
                                  @RequestParam("text") String text) {
        emailService.sendSimpleEmail(to, subject, text);
        return "success";
    }

    // 發(fā)送HTML郵件接口
    @PostMapping("/sendHtmlEmail")
    public String sendHtmlEmail(@RequestParam("to") String to,
                                @RequestParam("subject") String subject,
                                @RequestParam("htmlContent") String htmlContent) {
        emailService.sendHtmlEmail(to, subject, htmlContent);
        return "success";
    }

    // 發(fā)送帶附件的郵件接口
    @PostMapping("/sendEmailWithAttachment")
    public String sendEmailWithAttachment(@RequestParam("to") String to,
                                          @RequestParam("subject") String subject,
                                          @RequestParam("text") String text,
                                          @RequestParam("attachment") MultipartFile attachment) {
        emailService.sendEmailWithAttachment(to, subject, text, attachment);
        return "success";
    }


    // 發(fā)送模板郵件接口
    @PostMapping("/sendTemplateEmail")
    public String sendTemplateEmail(@RequestParam("to") String to,
                                    @RequestParam("subject") String subject,
                                    @RequestParam("templateName") String templateName) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("name", "CoderJia");
        variables.put("code", 12530);
        templateEmailService.sendTemplateEmail(to, subject, templateName, variables);
        return "success";
    }
}

發(fā)送效果

普通郵件

HTML郵件

帶附件郵件

模板郵件

7. 常見問題解決

7.1 連接超時(shí)

spring:
  mail:
    properties:
      mail:
        smtp:
          connectiontimeout: 5000
          timeout: 5000
          writetimeout: 5000

7.2 SSL證書問題

spring:
  mail:
    properties:
      mail:
        smtp:
          ssl:
            trust: "*"

7.3 中文亂碼

helper.setFrom(new InternetAddress(from, "發(fā)件人名稱", "UTF-8"));

8. 總結(jié)

本文詳細(xì)介紹了在SpringBoot 3中實(shí)現(xiàn)郵件發(fā)送功能的完整解決方案,包括基本配置、代碼實(shí)現(xiàn)、最佳實(shí)踐、安全建議等內(nèi)容。通過采用異步發(fā)送、重試機(jī)制、限流等最佳實(shí)踐,可以構(gòu)建一個(gè)健壯的郵件發(fā)送系統(tǒng)。在實(shí)際應(yīng)用中,要根據(jù)具體需求選擇合適的實(shí)現(xiàn)方式,同時(shí)注意安全性和性能的平衡。

到此這篇關(guān)于重學(xué)SpringBoot3之如何發(fā)送Email郵件功能的文章就介紹到這了,更多相關(guān)SpringBoot3發(fā)送Email內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 大廠禁止SpringBoot在項(xiàng)目使用Tomcat容器原理解析

    大廠禁止SpringBoot在項(xiàng)目使用Tomcat容器原理解析

    這篇文章主要為大家介紹了大廠禁止SpringBoot在項(xiàng)目使用Tomcat原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • SpringBoot RestTemplate 簡(jiǎn)單包裝解析

    SpringBoot RestTemplate 簡(jiǎn)單包裝解析

    這篇文章主要介紹了SpringBoot RestTemplate 簡(jiǎn)單包裝解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • MyBatis-Plus?Page?分頁不生效的問題解決

    MyBatis-Plus?Page?分頁不生效的問題解決

    分頁是常見的一種功能,本文主要介紹了MyBatis-Plus?Page分頁不生效的問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • 解決IDEA 左側(cè)Project中沒有out文件夾的問題

    解決IDEA 左側(cè)Project中沒有out文件夾的問題

    這篇文章主要介紹了解決IDEA 左側(cè)Project中沒有out文件夾的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Springboot中集成Swagger2框架的方法

    Springboot中集成Swagger2框架的方法

    這篇文章主要介紹了Springboot中集成Swagger2框架的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-12-12
  • SpringBoot添加License的多種方式

    SpringBoot添加License的多種方式

    License指的是版權(quán)許可證,當(dāng)我們開發(fā)完系統(tǒng)后,如果不想讓用戶一直白嫖使用,比如說按時(shí)間續(xù)費(fèi),License的作用就有了。我們可以給系統(tǒng)指定License的有效期,控制系統(tǒng)的可用時(shí)間。
    2021-06-06
  • SSH框架網(wǎng)上商城項(xiàng)目第4戰(zhàn)之EasyUI菜單的實(shí)現(xiàn)

    SSH框架網(wǎng)上商城項(xiàng)目第4戰(zhàn)之EasyUI菜單的實(shí)現(xiàn)

    SSH框架網(wǎng)上商城項(xiàng)目第4戰(zhàn)之EasyUI菜單的實(shí)現(xiàn),本文主要使用EasyUI技術(shù)簡(jiǎn)單實(shí)現(xiàn)后臺(tái)菜單,感興趣的小伙伴們可以參考一下
    2016-05-05
  • idea安裝與配置及基本用法教程詳解

    idea安裝與配置及基本用法教程詳解

    這篇文章主要介紹了idea安裝與配置及基本用法教程詳解,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java輸入輸出流實(shí)例詳解

    Java輸入輸出流實(shí)例詳解

    這篇文章主要介紹了Java輸入輸出流,結(jié)合實(shí)例形式詳細(xì)分析了Java常見的輸入輸出常用操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2018-09-09
  • Java從源碼角度解析SpringMVC執(zhí)行流程

    Java從源碼角度解析SpringMVC執(zhí)行流程

    這篇文章主要介紹了Java從源碼角度解析SpringMVC執(zhí)行流程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04

最新評(píng)論