【Email】基于SpringBoot3.4.x集成发送邮件功能

【Email】基于SpringBoot3.4.x集成发送邮件功能

  • 摘要
  • 本地开发环境说明
  • pom.xml
  • 启动类
  • application.yaml
  • 写一个邮件模板
  • 定义模板引擎工具类
  • 定义一个邮件发送对象
  • 封装一个邮件发送器
  • 单元测试
    • 邮件模板单元测试
    • 发送邮件单元测试
  • 邮件效果
  • 参考资料

摘要

在业务系统开发过程中,经常有发送邮件的需求,希望可以系统在某个时候自动触发邮件,或者支持用户主动触发邮件,Spring Boot框架提供了发送邮件的功能,通过简单的配置即可实现。

有时候不仅要发送邮件,对邮件内容格式、样式还有更高要求,我们也可以利用模板引擎来实现,比如ThymeleafFreemarker等等。

本着"最新"原则,这篇文章依然采用最新版的Spring Boot 3.4.0OpenJDK最新LTS21IntelliJ IDEA最新社区版2024.3.1

本地开发环境说明

开发用到的主要框架、工具版本如下

开发依赖版本
Spring Boot3.4.0
spring-boot-starter-mail3.4.0
spring-boot-starter-thymeleaf3.4.0
JDK21
IntelliJ IDEA2024.3.1

工程目录结构大致如下
在这里插入图片描述

pom.xml

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

启动类

package com.wen3.demo.email;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @author: tangheng*/
@SpringBootApplication
public class EmailDemoApplication {public static void main(String[] args) {SpringApplication.run(EmailDemoApplication.class, args);}
}

application.yaml

spring:mail:host: "smtp.sina.com" # 发件服务器地址,不同邮件平台地址不同port: 25 #常用邮件端口25、109、110、143、465、995、993、994 如果开启了SSL安全则使用对应的端口号,25为非加密端口号username: xxxx@sina.com #发送邮件的账号password: xxxxxxxxxxxxxxxx #发送邮件账号的授权码,这里的授权码不是验证码.需要到邮箱default-encoding: utf-8 #设置编码properties: # 设置邮件超时时间防止服务器阻塞timeout: 5000connection-timeout: 5000write-timeout: 5000mail:smtp:auth: truestarttls:enable: truerequired: true

写一个邮件模板

email-template.html内容如下

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>[[${title}]]</title>
</head>
<body>
<div style="background-color:#ECECEC; padding: 15px;"><table cellpadding="0" align="center"style="width: 600px; margin: 0px auto; text-align: left; position: relative; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; font-size: 14px; font-family:微软雅黑, 黑体; line-height: 1.5; box-shadow: rgb(153, 153, 153) 0px 0px 5px; border-collapse: collapse; background-position: initial initial; background-repeat: initial initial;background:#fff;"><tbody><tr><th valign="middle"style="height: 25px; line-height: 25px; padding: 15px 35px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #42a3d3; background-color: #49bcff; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px;"><font face="微软雅黑" size="5" style="color: rgb(255, 255, 255); ">测试邮件</font></th></tr><tr><td><div style="padding:25px 35px 40px; background-color:#fff;"><h2 style="margin: 5px 0px; "><font color="#333333" style="line-height: 20px; "><font style="line-height: 22px; " size="4">亲爱的<b>[[${email}]]</b>用户,您好:</font></font></h2><p>首先感谢您加入【运维自助平台】!请在验证页面输入以下验证码:<br><b style="font-size: 18px">[[${code}]]</b><br>本验证码5分钟内有效,为了保障您的账户安全,请勿向任何人提供此验证码。感谢您的支持!<br>如果您有什么疑问可以联系管理员,Email: admin@xxx.com</p><p align="right">运维自助平台</p><p align="right">[[${date}]]</p><div style="width:700px;margin:0 auto;"><div style="padding:10px 10px 0;border-top:1px solid #ccc;color:#747474;margin-bottom:20px;line-height:1.3em;font-size:12px;"><p>本邮件系统自动发送,请勿回复!<br>请保管好您的邮箱,避免账号被他人盗用</p><p>©运维自助平台</p></div></div></div></td></tr></tbody></table>
</div>
</body>
</html>

定义模板引擎工具类

TemplateUtil.java内容如下

package com.wen3.demo.email.template;import cn.hutool.core.date.DateUtil;
import jakarta.annotation.Resource;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;import java.util.Date;/*** @author: tangheng*/
@Service
@FieldDefaults(level = AccessLevel.PRIVATE)
public class TemplateUtil {@Resourceprivate TemplateEngine templateEngine;/*** 获得验证码模板*/public String getCaptchaTempl(String email, String code) {Context context = new Context();//设置模板所需的参数context.setVariable("title","验证码");context.setVariable("email",email);context.setVariable("code",code);context.setVariable("date", DateUtil.format(new Date(),"yyyy-MM-dd hh:mm:ss"));//通过模板类将动态参数传入HTML模板,并返回模板内容 参数一:模板名字,参数二:动态参数Web文本String content = templateEngine.process("/email-template", context);return content;}
}

定义一个邮件发送对象

package com.wen3.demo.email.dto;import lombok.*;
import lombok.experimental.Accessors;
import lombok.experimental.FieldDefaults;
import lombok.experimental.SuperBuilder;import java.util.List;/*** 邮件发送对象** @author: tangheng*/
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@SuperBuilder
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class EMailCmd {List<String> tos;String subject;String text;
}

封装一个邮件发送器

package com.wen3.demo.email.sender;import com.wen3.demo.email.dto.EMailCmd;
import jakarta.annotation.Resource;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.AccessLevel;
import lombok.SneakyThrows;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;/*** @author: tangheng*/
@Slf4j
@Service
@FieldDefaults(level = AccessLevel.PRIVATE)
public class EmailSender {@ResourceJavaMailSender mailSender;public void sendEMail(EMailCmd eMailCmd) {try {SimpleMailMessage simpleMailMessage = new SimpleMailMessage();simpleMailMessage.setFrom("太空眼睛<best5721@sina.com>"); //设置发送邮件账号simpleMailMessage.setTo(eMailCmd.getTos().toArray(String[]::new)); //设置接收邮件的人,可以多个simpleMailMessage.setSubject(eMailCmd.getSubject()); //设置发送邮件的主题simpleMailMessage.setText(eMailCmd.getText()); //设置发送邮件的内容mailSender.send(simpleMailMessage);} catch (MailException e) {log.error("邮件发送失败!");}}@SneakyThrowspublic void sendHtmlEMail(EMailCmd eMailCmd) {try {MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper minehelper = new MimeMessageHelper(message, true);minehelper.setFrom("太空眼睛<best5721@sina.com>");
//            minehelper.setFrom("best5721@sina.com", "太空眼睛");minehelper.setTo(eMailCmd.getTos().toArray(String[]::new)); //设置接收邮件的人,可以多个minehelper.setSubject(eMailCmd.getSubject()); //设置发送邮件的主题minehelper.setText(eMailCmd.getText(),true); //设置发送邮件的内容 第二个设置为true则可以发送带HTML的邮件mailSender.send(message);} catch (MessagingException e) {log.error("邮件发送失败!");}}
}

邮件地址的格式可以写成best5721@sina.com
也可以写成太空眼睛<best5721@sina.com>

单元测试

邮件模板单元测试

package com.wen3.demo.email.template;import cn.hutool.core.util.RandomUtil;
import com.wen3.demo.email.EmailDemoSpringBootTestBase;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.*;class TemplateUtilTest extends EmailDemoSpringBootTestBase {@ResourceTemplateUtil templateUtil;@Testvoid getCaptchaTempl() {String email = "tangheng";String code = RandomUtil.randomNumbers(5);String testResult = templateUtil.getCaptchaTempl(email,code);log.info("testResult: {}", testResult);assertNotNull(testResult);}
}

发送邮件单元测试

package com.wen3.demo.email.sender;import cn.hutool.core.util.RandomUtil;
import com.wen3.demo.email.EmailDemoSpringBootTestBase;
import com.wen3.demo.email.dto.EMailCmd;
import com.wen3.demo.email.template.TemplateUtil;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.mail.MailProperties;import java.util.List;import static org.junit.jupiter.api.Assertions.*;class EmailSenderTest extends EmailDemoSpringBootTestBase {@ResourceEmailSender emailSender;@ResourceTemplateUtil templateUtil;@ResourceMailProperties mailProperties;@Testvoid sendHtmlEMail() {String to = "friendly1234@126.com";EMailCmd eMailCmd = EMailCmd.builder().tos(List.of(to)).subject("测试邮件").text(templateUtil.getCaptchaTempl(to, RandomUtil.randomNumbers(5))).build();emailSender.sendHtmlEMail(eMailCmd);}
}

邮件效果

在这里插入图片描述

参考资料

  • SpringBoot集成EMail

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/490427.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hoppscotch VS postman

下载&#xff1a;https://hoppscotch.com/download 使用&#xff1a;

使用LSTM神经网络对股票日线行情进行回归训练(Pytorch版)

版权声明&#xff1a;本文为博主原创文章&#xff0c;如需转载请贴上原博文链接&#xff1a;使用LSTM神经网络对股票日线行情进行回归训练&#xff08;Pytorch版&#xff09;-CSDN博客 前言&#xff1a;近期在尝试使用lstm对股票日线数据进行拟合&#xff0c;初见成型但是效果不…

Web项目图片视频加载缓慢/首屏加载白屏

Web项目图片视频加载缓慢/首屏加载白屏 文章目录 Web项目图片视频加载缓慢/首屏加载白屏一、原因二、 解决方案2.1、 图片和视频的优化2.1.1、压缩图片或视频2.1.2、 选择合适的图片或视频格式2.1.3、 使用图片或视频 CDN 加速2.1.4、Nginx中开启gzip 三、压缩工具推荐 一、原因…

MATLAB选取向量中最大的若干个值个值,并返回所在位置的函数

在 MATLAB 中&#xff0c;可以使用 maxk 函数来选取向量中最大的 ( k ) 个值&#xff0c;并返回它们的索引位置。maxk 函数非常方便&#xff0c;适用于需要获取前几个最大值的情形。 文章目录 语法 示例输出结果总结 语法 [M, I] maxk(A, k)A 是输入向量。k 是要选择的最大值…

PDFMathTranslate,PDF多语言翻译,批量处理,学术论文,双语对照(WIN/MAC)

分享一个非常实用的PDF文档翻译项目——PDFMathTranslate。作为一个经常逛GitHub的开发者&#xff0c;我总喜欢翻看各种项目附带的论文&#xff0c;虽然大多时候是瞎研究&#xff0c;但却乐在其中。该项目能够完美保留公式、图表、目录和注释&#xff0c;对于需要阅读外文文献的…

Mvc、Springmvc框架

一.Mvc&#xff1a; 1.概念&#xff1a; MVC它是一种设计理念。把程序按照指定的结构来划分: Model模型 、View视图 、Controller控制层&#xff1b; 结构图&#xff1a; 二.Springmvc: 1.概念&#xff1a; springmvc框架它是spring框架的一个分支。它是按照mvc架构思想设计…

item2 for macos

安装Item2 brew install iterm2 查看终端类型 cat /etc/shells Mac OS X 10.15 已经将默认的shell从Bash换成了zsh&#xff0c;所以不用安装&#xff0c;10.15以前的可以使用下面的命令进行安装 brew install zsh 安装Oh My ZSH # curl sh -c "$(curl -fsSL https://ra…

PyTorch基本使用-自动微分模块

学习目的&#xff1a;掌握自动微分模块的使用 训练神经网络时&#xff0c;最常用的算法就是反向传播。在该算法中&#xff0c;参数&#xff08;模型权重&#xff09;会根据损失函数关于对应参数的梯度进行调整。为了计算这些梯度&#xff0c;PyTorch 内置了名为 torch.autogra…

使用rust语言创建python模块(pyo3+maturin)

1. 首先使用conda创建python虚拟环境&#xff08;已创建的可省略&#xff09; >conda create --prefixE:\python_envs\rust_python python3.11 2. 激活python虚拟环境 conda activate rust_python 3. 安装maturin pip install maturin 4. 创建rust项目 >cd E:\py…

Linux 网络流量控制 - 实现概述

摘要 Linux 提供了一整套丰富的流量控制(traffic control)功能。本文档概述了相应的内核代码设计&#xff0c;描述了其结构&#xff0c;并通过描述一种新的排队策略来说明新元素的添加。 1 引言 最近的Linux内核提供了多种流量控制功能。Alexey Kuznetsov&#xff08;kuznet…

哈希【C++实现】

目录 哈希1. unordered系列关联式容器2.unordered_map2.1unordered_map的文档介绍2.2unordered_map的接口介绍 3.unordered_set3.1unordered_set的文档介绍3.2unordered_set的接口 4.相关OJ题5.两种容器的区别5.1性能区别 6.底层结构(重要&#xff01;&#xff01;&#xff01;…

文件包含漏洞下 日志文件的利用 session文件竞争

普及 日志文件记录了一下登录者的信息 访问者ip&#xff1a;127.0.0.1 访问日期 请求方式&#xff1a;GET 请求链接&#xff1a;/dvwa/phpinfo.php 请求参数&#xff1a;PHPE9568F34-D428-11d2-A769-00AA001ACF42 HTTP协议&#xff1a;HTTP/1.1 返回转态码&#xff1a;200 返…

动态规划子序列问题系列一>最长数对链

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public int findLongestChain(int[][] pairs) {Arrays.sort(pairs, (a,b)->(a[0]-b[0]));int n pairs.length;int[] dp new int[n];for(int i 0; i < n; i) dp[i] 1;int ret 1;for(int i 1; i < n; i){f…

uni-app创建微信小程序

UniApp 是一个基于 Vue.js 语法的跨平台开发框架&#xff0c;它允许开发者使用一套代码构建适用于 iOS 、 Android 、 Web 以及各种小程序和快应用的应用程序 一、环境搭建 安装使用教程&#xff1a;https://blog.csdn.net/YuanFudao/article/details/132384692 二、项目基本…

如何快速搭建若依管理系统?

1、下载若依管理系统前后端分离版代码至本地&#xff08;当前版本为RuoYi v3.8.8&#xff09;&#xff1a; RuoYi-Vue: &#x1f389; 基于SpringBoot&#xff0c;Spring Security&#xff0c;JWT&#xff0c;Vue & Element 的前后端分离权限管理系统&#xff0c;同时提供…

6.2 MapReduce工作原理

MapReduce工作原理涉及将大数据集分割成小块并行处理。Map任务读取数据块并输出中间键值对&#xff0c;而Reduce任务则处理这些排序后的数据以生成最终结果。MapTask工作包括读取数据、应用Map函数、收集输出、内存溢出时写入磁盘以及可选的Combiner局部聚合。ReduceTask工作则…

金融分析-Transformer模型(基础理论)

Transformer模型 1.基本原理 transformer的core是注意力机制&#xff0c;其本质就是编码器-解码器。他可以通过多个编码器进行编码&#xff0c;再把编码完的结果输出给解码器进行解码&#xff0c;然后得到最终的output。 1.1编码器 数据在编码器中会经过一个self-attention的…

创建vue3项目步骤以及安装第三方插件步骤【保姆级教程】

&#x1f399;座右铭&#xff1a;得之坦然&#xff0c;失之淡然。 &#x1f48e;擅长领域&#xff1a;前端 是的&#xff0c;我需要您的&#xff1a; &#x1f9e1;点赞❤️关注&#x1f499;收藏&#x1f49b; 是我持续下去的动力&#xff01; 目录 一. 简单汇总一下创建…

大模型底座 Transformer 的核心技术解析

1. 引言 说明目标 在深度学习领域&#xff0c;Transformer架构已成为近年来最重要的技术突破之一。它最早由Vaswani等人在2017年的论文《Attention is All You Need》中提出&#xff0c;迅速成为自然语言处理&#xff08;NLP&#xff09;和其他序列建模任务的核心工具。传统方法…

利用git上传项目到GitHub

GitHub是基于git实现的代码托管。git是目前最好用的版本控制系统了&#xff0c;非常受欢迎&#xff0c;比之svn更好。 GitHub可以免费使用&#xff0c;并且快速稳定。 利用GitHub&#xff0c;你可以将项目存档&#xff0c;与其他人分享交流&#xff0c;并让其他开发者帮助你一…