当前位置: 首页 > news >正文

基于spring boot实现邮箱发送和邮箱验证

目录

    • 一、邮箱发送实现
      • 1. 开通邮箱服务
      • 2. 添加邮箱依赖
      • 3.添加配置
      • 4.添加邮箱通用类
      • 5. 测试类
    • 二、邮箱验证实现
      • 1.添加依赖
      • 2. 添加配置
      • 3.添加controller
      • 4. 测试

项目地址: https://gitee.com/nssnail/springboot-email

一、邮箱发送实现

1. 开通邮箱服务

使用qq邮箱、163邮箱都行,其他有邮箱服务功能的都可以,这里以163邮箱为例

登录163邮箱,然后在设置那里选择POP3/SMTP/IMAP

在这里插入图片描述

开通IMAP/SMTP服务

在这里插入图片描述

开通后会有个授权码,记录下来,后面需要用到

在这里插入图片描述

2. 添加邮箱依赖

添加pom文件

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

3.添加配置

host是开通smtp时会有个地址的

username填的是邮箱账号

password填的是刚才上面开通smtp的授权码,请注意不是邮箱密码,是授权码

注:

1.配置里面有个port的配置是默认端口,尽量不要自己去设置,不然可能会无法访问,以下配置是没有port的

2.配置错误可以尝试把注释去掉,因为有可能会因为复制过去的编码问题影响

spring:mail:host: smtp.163.com # smtp地址,开通的时候会显示username: xxxxx@163.com # 你的邮箱账号password: ****** # 你的邮箱授权码properties:mail:smtp:auth: truestarttls:enable: trueprotocol: smtp

4.添加邮箱通用类

这里是用了hutools的工具和lombok的Slf4j日志,视情况而添加

<!-- 工具类 -->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.2</version>
</dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.4</version><scope>provided</scope>
</dependency>
@Service
@Slf4j
public class EmailService {@Autowiredprivate JavaMailSender mailSender;@Value("${spring.mail.username}")private String username;/*** 发送文本邮件** @param to      收件人地址* @param subject 邮件主题* @param content 邮件内容* @param cc      抄送地址*/public  void sendSimpleMail(String to, String subject, String content, String... cc) {SimpleMailMessage message = new SimpleMailMessage();message.setFrom(username);message.setTo(to);message.setSubject(subject);message.setText(content);if (ArrayUtil.isNotEmpty(cc)) {message.setCc(cc);}mailSender.send(message);}/*** 发送HTML邮件** @param to      收件人地址* @param subject 邮件主题* @param content 邮件内容* @param cc      抄送地址*/public  void sendHtmlMail(String to, String subject, String content, String... cc) {try {MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true,"UTF-8");helper.setFrom(username);helper.setTo(to);helper.setSubject(subject);helper.setText(content, true);if (ArrayUtil.isNotEmpty(cc)) {helper.setCc(cc);}mailSender.send(message);} catch (MessagingException e) {log.error("发送邮件失败,收件人:{}", to, e);}}/*** 发送带附件的邮件** @param to       收件人地址* @param subject  邮件主题* @param content  邮件内容* @param filePath 附件地址* @param cc       抄送地址*/public  void sendAttachmentsMail(String to, String subject, String content, String filePath, String... cc) {try {MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true,"UTF-8");helper.setFrom(username);helper.setTo(to);helper.setSubject(subject);helper.setText(content, true);if (ArrayUtil.isNotEmpty(cc)) {helper.setCc(cc);}FileSystemResource file = new FileSystemResource(new File(filePath));String fileName = filePath.substring(filePath.lastIndexOf(File.separator));helper.addAttachment(fileName, file);mailSender.send(message);} catch (MessagingException e) {log.error("发送邮件失败,收件人:{}", to, e);}}/*** 发送正文中有静态资源的邮件** @param to      收件人地址* @param subject 邮件主题* @param content 邮件内容* @param rscPath 静态资源地址* @param rscId   静态资源id* @param cc      抄送地址*/public  void sendResourceMail(String to, String subject, String content, String rscPath, String rscId, String... cc) {try {MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true,"UTF-8");helper.setFrom(username);helper.setTo(to);helper.setSubject(subject);helper.setText(content, true);if (ArrayUtil.isNotEmpty(cc)) {helper.setCc(cc);}FileSystemResource res = new FileSystemResource(new File(rscPath));helper.addInline(rscId, res);mailSender.send(message);} catch (MessagingException e) {log.error("发送邮件失败,收件人:{}", to, e);}}
}

5. 测试类

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes={EmailServiceApplication.class, EmailServiceTest.class})
public class EmailServiceTest {@Resourceprivate EmailService emailService;@Testpublic void test(){emailService.sendSimpleMail("1191986647@qq.com","测试","测试");}
}

在这里插入图片描述

二、邮箱验证实现

实现验证需要使用redis,本章节不介绍如何使用redis,请自行搭建

1.添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><!-- jedis连接 -->
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId>
</dependency>

2. 添加配置

yaml配置

spring:redis:host: localhost # redis地址port: 6379database: 0  password: 123456 # 密码,无密码可不填

序列化配置,新建一个config包,并添加RedisConfig类

@Configuration
public class RedisConfig {@Beanpublic StringRedisTemplate redisTemplate(RedisConnectionFactory factory) {StringRedisTemplate template = new StringRedisTemplate(factory);template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new StringRedisSerializer());return template;}
}

3.添加controller

@RestController
@RequestMapping("/api")
public class VerificationController {@Autowiredprivate EmailService emailService;@Autowiredprivate StringRedisTemplate redisTemplate;@PostMapping("/sendCode")public String sendCode(@RequestParam String email) {// 生成验证码String code = String.valueOf((int)((Math.random() * 9 + 1) * 100000));emailService.sendHtmlMail(email, "【邮箱验证码】欢迎使用xxx系统", "<p>您的邮箱验证码是:<p><p style=\" font-weight: bold;text-align: center;color: red;\">"+code+"</p>" );// 存储验证码到 Redis,设置过期时间为 5 分钟ValueOperations<String, String> ops = redisTemplate.opsForValue();redisTemplate.delete(email);ops.set(email, code, 5, TimeUnit.MINUTES);return "验证码已发送";}@PostMapping("/verifyCode")public String verifyCode(@RequestParam String email, @RequestParam String code) {// 从 Redis 获取验证码ValueOperations<String, String> ops = redisTemplate.opsForValue();String storedCode = ops.get(email);if (storedCode != null && storedCode.equals(code)) {redisTemplate.delete(email);return "邮箱验证成功";} else {return "验证码错误或者已失效";}}
}

4. 测试

发送

在这里插入图片描述

在这里插入图片描述

验证

在这里插入图片描述
在这里插入图片描述

相关文章:

基于spring boot实现邮箱发送和邮箱验证

目录 一、邮箱发送实现1. 开通邮箱服务2. 添加邮箱依赖3.添加配置4.添加邮箱通用类5. 测试类 二、邮箱验证实现1.添加依赖2. 添加配置3.添加controller4. 测试 项目地址: https://gitee.com/nssnail/springboot-email 一、邮箱发送实现 1. 开通邮箱服务 使用qq邮箱、163邮箱都…...

华清作业day56

SQLite特性&#xff1a; 零配置一无需安装和管理配置&#xff1b;储存在单一磁盘文件中的一个完整的数据库&#xff1b;数据库文件可以在不同字节顺序的机器间自由共享&#xff1b;支持数据库大小至2TB&#xff1b;足够小&#xff0c;全部源码大致3万行c代码&#xff0c;250KB…...

【FPGA】VHDL:八段码到8421BCD码转换电路

目录 EDA设计基础练习题 &#xff1a; 实验要求如下&#xff1a; 代码 八段码到8421BCD码转换电路 8421BCD码到八段码转换电路 八段码到8421BCD~运行结果展示 8421BCD转八段码~运行结果展示 特别注意 软件&#xff1a;Quartus II 13.0 (64-bit) 语言&#xff1a;VHDL E…...

docker安装、运行

1、安装 之前有docker的话&#xff0c;需要先卸载旧版本&#xff1a; sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 安装之前需要安装yum工具&#xff1a; sud…...

新型RedAlert勒索病毒针对VMWare ESXi服务器

前言 RedAlert勒索病毒又称为N13V勒索病毒&#xff0c;是一款2022年新型的勒索病毒&#xff0c;最早于2022年7月被首次曝光&#xff0c;主要针对Windows和Linux VMWare ESXi服务器进行加密攻击&#xff0c;到目前为止该勒索病毒黑客组织在其暗网网站上公布了一名受害者&#x…...

qt-C++笔记之判断一个QLabel上有没有load图片

qt-C笔记之判断一个QLabel上有没有load图片 code review! 在Qt框架中&#xff0c;QLabel是用来显示文本或者图片的一个控件。如果你想判断一个QLabel控件上是否加载了图片&#xff0c;你可以检查它的pixmap属性。pixmap属性会返回一个QPixmap对象&#xff0c;如果没有图片被加…...

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Menu组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Menu组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Menu组件 以垂直列表形式显示的菜单。 子组件 包含MenuItem、MenuItemGroup子组…...

vue三种路由守卫详解

在 Vue 中&#xff0c;可以通过路由守卫来实现路由鉴权。Vue 提供了三种路由守卫&#xff1a;全局前置守卫、全局解析守卫和组件内的守卫。 全局前置守卫 通过 router.beforeEach() 方法实现&#xff0c;可以在路由跳转之前进行权限判断。在这个守卫中&#xff0c;可以根据用…...

【Linux】线程概念和线程控制

线程概念 一、理解线程1. Linux中的线程2. 重新定义线程和进程3. 进程地址空间之页表4. 线程和进程切换5. 线程的优点6. 线程的缺点7. 线程异常8. 线程用途9. 线程和进程 二、线程控制1. pthread 线程库&#xff08;1&#xff09;pthread_create()&#xff08;2&#xff09;pth…...

maven创建webapp+Freemarker组件的实现

下载安装配置maven Maven官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘123云盘为您提供Maven最新版正式版官方版绿色版下载,Maven安卓版手机版apk免费下载安装到手机,支持电脑端一键快捷安装https://www.123pan.com/s/9QRqVv-TcUY.html链接为3.6.2-3.6.3的版本 下载解…...

Stable Diffusion 模型下载:Samaritan 3d Cartoon SDXL(撒玛利亚人 3d 卡通 SDXL)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十...

Oracle系列之十:Oracle正则表达式

Oracle正则表达式 1. 基本语法2. POSIX字符类3. 正则表达式函数4. 常用正则表达式 正则表达式 (Regular expression) 是一种强大的文本处理工具&#xff0c;Oracle数据库自9i版本开始引入了正则表达式支持&#xff0c;可帮助开发者快速而准确地匹配、查找和替换字符串&#xff…...

php基础学习之运算符(重点在连接符和错误抑制符)

运算符总结 在各种编程语言中&#xff0c;常用的运算符号有这三大类&#xff1a; 算术运算符&#xff1a;&#xff0c;-&#xff0c;*&#xff0c;/&#xff0c;%位运算符&#xff1a;&&#xff0c;|&#xff0c;^&#xff0c;<<&#xff0c;>>赋值运算符&…...

【CC工具箱1.2.0】更新_免费无套路,60+个工具,原码放出

CC工具箱目前已经更新到1.2.0版本&#xff0c;完全免费无套路。 适用版本ArcGIS Pro 3.0及以上。 欢迎大家使用&#xff0c;反馈bug&#xff0c;以及提出需求和意见&#xff0c;时间和能力允许的话我会尽量满足要求。 如有关于工具的使用问题和需求建议&#xff0c;可以加下…...

Java 将TXT文本文件转换为PDF文件

与TXT文本文件&#xff0c;PDF文件更加专业也更适合传输&#xff0c;常用于正式报告、简历、合同等场合。项目中如果有使用Java将TXT文本文件转为PDF文件的需求&#xff0c;可以查看本文中介绍的免费实现方法。 免费Java PDF库 本文介绍的方法需要用到Free Spire.PDF for Java…...

Sketch 99.1 for macOS

Sketch 99.1 for macOS 概述 这个程序是对矢量绘图的创新性和焕然一新的看法。它特意采用了极简主义的设计&#xff0c;基于一个大小无限、图层自由的绘图空间&#xff0c;没有调色板、面板、菜单、窗口和控件。 此外&#xff0c;它提供了强大的矢量绘图和文本工具&#xff0c;…...

Apache 神禹(shenyu)源码阅读(一)——Admin向Gateway的数据同步(Admin端)

源码版本&#xff1a;2.6.1 单机源码启动项目 启动教程&#xff1a;社区新人开发者启动及开发防踩坑指南 源码阅读 前言 开了个新坑&#xff0c;也是第一次阅读大型项目源码&#xff0c;写文章记录。 在写文章前&#xff0c;已经跑了 Divide 插件体验了一下&#xff08;体…...

Prompt Tuning:深度解读一种新的微调范式

阅读该博客&#xff0c;您将系统地掌握如下知识点&#xff1a; 什么是预训练语言模型&#xff1f; 什么是prompt&#xff1f;为什么要引入prompt&#xff1f;相比传统fine-tuning有什么优势&#xff1f; 自20年底开始&#xff0c;prompt的发展历程&#xff0c;哪些经典的代表…...

Unity3d Shader篇(五)— Phong片元高光反射着色器

文章目录 前言一、Phong片元高光反射着色器是什么&#xff1f;1. Phong片元高光反射着色器的工作原理2. Phong片元高光反射着色器的优缺点优点缺点 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数 三、效果四、总…...

sql求解连续两个以上的空座位

Q&#xff1a;查找电影院所有连续可用的座位。 返回按 seat_id 升序排序 的结果表。 测试用例的生成使得两个以上的座位连续可用。 结果表格式如下所示。 A:我们首先找出所有的空座位&#xff1a;1&#xff0c;3&#xff0c;4&#xff0c;5 按照seat_id排序&#xff08;上面已…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...