SPRING BOOT发送邮件验证码(Gmail邮箱)
SPRING BOOT邮件发送验证码
一、Gmail邮箱配置
1、进入Gmail(https://mail.google.com)
2、打开谷歌右上角设置
3、启用POP/IMP
4、启用两步验证(https://myaccount.google.com/security)
5、建立应用程式密码
6、复制保存应用程式密码
二、代码
1、引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>
2、application.properties文件配置
spring.mail.host=smtp.gmail.com
# 邮件服务器端口号
spring.mail.port=587
# 邮件发送方的电子邮件地址
spring.mail.username=你的Gmail邮箱账号
# 邮件发送方的密码或应用程序专用密码(如果启用了两步验证)
spring.mail.password=应用程序专用密码
# 启用TLS加密
spring.mail.properties.mail.smtp.starttls.enable=true
# 验证邮件服务器的身份
spring.mail.properties.mail.smtp.auth=true
# 邮件传输协议
spring.mail.properties.mail.transport.protocol=smtp
3、EmailUtil邮件工具类
@Service
public class EmailUtil implements EmailService
{private final Logger logger = LoggerFactory.getLogger(this.getClass());//Spring Boot 提供了一个发送邮件的简单抽象,使用的是下面这个接口,这里直接注入即可使用@Autowiredprivate JavaMailSender mailSender;// 配置文件中我的谷歌邮箱@Value("${spring.mail.username}")private String from;/*** 简单文本邮件* @param to 收件人* @param subject 主题* @param content 内容*/@Overridepublic void sendSimpleMail(String to, String subject, String content) {//创建SimpleMailMessage对象SimpleMailMessage message = new SimpleMailMessage();//邮件发送人message.setFrom(from);//邮件接收人message.setTo(to);//邮件主题message.setSubject(subject);//邮件内容message.setText(content);//发送邮件mailSender.send(message);}/*** html邮件* @param to 收件人,多个时参数形式 :"xxx@xxx.com,xxx@xxx.com,xxx@xxx.com"* @param subject 主题* @param content 内容*/@Overridepublic void sendHtmlMail(String to, String subject, String content) {//获取MimeMessage对象MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper messageHelper;try {messageHelper = new MimeMessageHelper(message, true);//邮件发送人messageHelper.setFrom(from);//邮件接收人,设置多个收件人地址InternetAddress[] internetAddressTo = InternetAddress.parse(to);messageHelper.setTo(internetAddressTo);//messageHelper.setTo(to);//邮件主题message.setSubject(subject);//邮件内容,html格式messageHelper.setText(content, true);//发送mailSender.send(message);//日志信息logger.info("邮件已经发送。");} catch (Exception e) {logger.error("发送邮件时发生异常!", e);}}/*** 带附件的邮件* @param to 收件人* @param subject 主题* @param content 内容* @param filePath 附件*/@Overridepublic void sendAttachmentsMail(String to, String subject, String content, String filePath) {MimeMessage message = mailSender.createMimeMessage();try {MimeMessageHelper helper = new MimeMessageHelper(message, true);helper.setFrom(from);helper.setTo(to);helper.setSubject(subject);helper.setText(content, true);FileSystemResource file = new FileSystemResource(new File(filePath));String fileName = filePath.substring(filePath.lastIndexOf(File.separator));helper.addAttachment(fileName, file);mailSender.send(message);//日志信息logger.info("邮件已经发送。");} catch (Exception e) {logger.error("发送邮件时发生异常!", e);}}/*** 验证邮箱格式* @param email* @return*/public boolean isEmail(String email) {if (email == null || email.length() < 1 || email.length() > 256) {return false;}Pattern pattern = Pattern.compile("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");return pattern.matcher(email).matches();}
}
EmailService
public interface EmailService {/*** 发送文本邮件** @param to 收件人* @param subject 主题* @param content 内容*/void sendSimpleMail(String to, String subject, String content);/*** 发送HTML邮件** @param to 收件人* @param subject 主题* @param content 内容*/public void sendHtmlMail(String to, String subject, String content);/*** 发送带附件的邮件** @param to 收件人* @param subject 主题* @param content 内容* @param filePath 附件*/public void sendAttachmentsMail(String to, String subject, String content, String filePath);
}
4、验证码存储/判断/删除
CodeUtil
@Service
public class CodeUtil {@Autowiredprivate StringRedisTemplate redisTemplate;public String generateVerificationCode() {// 生成6位随机数字验证码return String.valueOf((int) ((Math.random() * 9 + 1) * 100000));}// 验证验证码是否正确public boolean verifyCode(String userId, String code,String key) {key = key + userId;String storedCode = redisTemplate.opsForValue().get(key);return code.equals(storedCode);}//删除redis中验证码public void deleteCode(String userId,String key) {key = key + userId;redisTemplate.delete(key);}
}
存储验证码
//写在需要发送验证码的地方//存储时间private static final int EXPIRATION_TIME_IN_MINUTES = 3;//键名private static final String KEY_PREFIX =="xxx";key=KEY_PREFIX+"123456"
redisTemplate.opsForValue().set(key, 随机数字验证码, EXPIRATION_TIME_IN_MINUTES, TimeUnit.MINUTES);
相关文章:
SPRING BOOT发送邮件验证码(Gmail邮箱)
SPRING BOOT邮件发送验证码 一、Gmail邮箱配置 1、进入Gmail(https://mail.google.com) 2、打开谷歌右上角设置 3、启用POP/IMP 4、启用两步验证(https://myaccount.google.com/security) 5、建立应用程式密码 6、复制保存应用程式密码 二、代码 1、引入依赖 <d…...
Liunx安装FTP和SFTP
ftp端口:20/21 sftp端口:22 一、ftp 1、安装ftp yum install vsftpd #安装ftp 服务 (1)查看ftp服务的状态 命令:service vsftpd status PS:提示vsftpd: command not found,修改PATH的环境…...
【Mars3d】new mars3d.layer.GeoJsonLayer({不规则polygon加载label不在正中间的解决方案
问题: 1.new mars3d.layer.GeoJsonLayer({type: "polygon",在styleOptions里配置label的时候,发现这个 不规则polygon加载的时候,会出现label不在中心位置。 graphicLayer new mars3d.layer.GeoJsonLayer({ name: "全国省界…...
怎么快速修复mfc140.dll文件?解决mfc140.dll缺失的方法
面对计算机报告的 mfc140.dll 文件遗失错误,这通常表明系统中缺少一个关键的动态链接库文件,该文件对于运行以 Microsoft Foundation Class (MFC) 库编写的程序十分重要,尤其是那些需要图形界面的应用程序和一些游戏。若没有这个文件&…...
安全防御之入侵检测与防范技术
安全防御中的入侵检测与防范技术主要涉及到入侵检测系统(IDS)和入侵防御技术(IPS)。 入侵检测系统(IDS)是一种对入侵行为自动进行检测、监控和分析的软件与硬件的组合系统。IDS通过从计算机网络或系统中的若…...
Leetcode2807. 在链表中插入最大公约数
Problem: 2807. 在链表中插入最大公约数 文章目录 题目思路注意点Code 题目思路 模拟插入流程: 检测当前节点是否有后置结点;将当前结点与后置结点的值做最大公约数处理得到新结点的值,然后插入到当前结点之后;再将检测结点向后…...
MySQL-DML
DML是数据操纵语言,用来对表中数据进行增删改操纵。 添加数据:INSERT 1.给指定字段添加数据:INSERT INTO 表名(字段名1,字段名2,...)VALUES(值1,值2); 2.给全部字段添加数据:INSERT INTO 表名VALUES(值1,值2) 3.给指定字段批量添…...
开源项目 | 完整部署流程、一款开源人人可用的开源数据可视化分析工具
📚 项目介绍 在互联网数据大爆炸的这几年,各类数据处理、数据可视化的需求使得 GitHub 上诞生了一大批高质量的 BI 工具。 借助这些 BI 工具,我们能够大幅提升数据分析效率、生成更高质量的项目报告,让用户通过直观的数据看到结…...
我建立了一个资源分享群
我建立了一个资源分享群 在为寻找资源犯愁? 在为分享资源犯愁? 一起加入分享资源群(是wx群哦)吧!你可以分享自己的资源帮助他人。你可以在群组里需求资源获取别人的帮助。发广告请绕行,会被拉黑哦 微信…...
C++中几个常用的类型选择模板函数
std::enable_if<B, T>::type 如果编译期满足B,那么返回类型T,否则编译报错 std::conditional<B, T, F>::type 如果编译期满足B,那么返回类型T,否则返回类型F 下面是一个示例,展示如何使用 std::condit…...
【LeetCode】1321. 餐馆营业额变化增长
表: Customer ------------------------ | Column Name | Type | ------------------------ | customer_id | int | | name | varchar | | visited_on | date | | amount | int | ------------------------ 在 SQL 中,(custo…...
【网络技术】【Kali Linux】Wireshark嗅探(八)动态主机配置协议(DHCP)
一、实验目的 本次实验使用 Wireshark (“网鲨”)流量分析工具进行网络流量嗅探,旨在初步了解动态主机配置协议(DHCP协议)的工作原理。 二、DHCP协议概述 动态主机配置协议( D ynamic H ost C onfigurat…...
算法29:不同路径问题(力扣62和63题)--针对算法28进行扩展
题目:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角࿰…...
openGauss学习笔记-188 openGauss 数据库运维-常见故障定位案例-core问题定位
文章目录 openGauss学习笔记-188 openGauss 数据库运维-常见故障定位案例-core问题定位188.1 磁盘满故障引起的core问题188.1.1 问题现象188.1.2 原因分析188.1.3 处理办法 188.2 GUC参数log_directory设置不正确引起的core问题188.2.1 问题现象188.2.2 原因分析188.2.3 处理办…...
kubernetes入门到进阶(5)
目录 镜像仓库:怎么用好docker hub这个宝藏 什么是镜像仓库(Registry) 什么是docker hub 如何在docker hub上挑选镜像 docker hub上进行概念股命名规则是什么 该怎么上传自己的镜像 离线环境该怎么办 小结 镜像仓库:怎么用好docke…...
【字典树Trie】LeetCode-139. 单词拆分
139. 单词拆分。 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 示例 1: 输入: s "leetcode&q…...
pytest常用的第三方插件介绍
本节介绍了如何安装和使用第三方插件。如果你想要编写自己的插件,请参阅“编写插件”。 通过pip可以轻松安装第三方插件: pip install pytest-NAME pip uninstall pytest-NAME如果已经安装了插件,pytest会自动找到并集成它,无需手…...
【经验】VSCode连接远程服务器(可以使用git管理、方便查看和编辑Linux源码)
1、查看OpenSSH Windows10通常自带OpenSSH不需要安装。 Windows10下检查是否已经安装OpenSSH的方法: 1)按下快捷键Win + X,选择Windows PoweShell(管理员) 2)输入以下指令: Get-WindowsCapability -Online | ? Name -like ‘OpenSSH*’ 3)如果电脑未安装OpenSSH,…...
机器学习-生存分析:如何基于随机生存森林训练乳腺癌风险评估模型?
一、 引言 乳腺癌是女性最常见的恶性肿瘤之一,也是全球范围内女性死亡率最高的癌症之一。据统计,每年全球有超过200万人被诊断为乳腺癌,其中约60万人死于该疾病。因此,乳腺癌的早期诊断和风险评估对于预防和治疗乳腺癌具有非常重要…...
MySQL学习笔记1: 数据库的简单介绍
目录 1. 数据库是什么2. 数据库这一类软件中的一些典型代表2.1. Oracle2.2. MySQL2.3. SQL Server2.4. SQLite (lite 轻量版) 3. 数据库的类型3.1. 关系型数据库3.2. 非关系型数据库 4. 总结 1. 数据库是什么 数据库是一类软件,这一类软件可以用来管理数据…...
【Docker】安装ELK(Docker Compose)
一、创建挂载目录 mkdir -p /docker/elk/elasticsearch/{plugins,data} mkdir -p /docker/elk/logstash 二、给目录授权 chmod 777 /docker/elk/elasticsearch/data 创建logstash配置文件 vim /docker/elk/logstash/logstash.conf input {tcp {mode => "server" h…...
【机器学习:欧氏距离 】机器学习中欧氏距离的理解和应用
【机器学习:欧氏距离 】机器学习中欧氏距离的理解和应用 距离公式二维更高的维度点以外的物体属性欧几里得距离的平方概括历史 在数学中,欧氏距离’是指欧氏空间中任意两点之间的直线距离。这种距离可以通过应用勾股定理来计算,利用两点的笛卡…...
系统安全及应用
1、基本安全措施 1.1、系统账号清理 在Linux系统中,除了用户手动创建的各种账号之外,还包括随系统或程序安装过程而生产的其他大量账号。除了超级用户root之外,其他大量账号只是用来维护系统运作、启动或保持服务进程,一般是不允…...
Danil Pristupov Fork(强大而易用的Git客户端) for Mac/Windows
在当今软件开发领域,团队协作和版本控制是非常重要的方面。在这个过程中,Git成为了最受欢迎的版本控制工具之一。然而,对于Git的使用,一个好的客户端是至关重要的。 今天,我们要为大家介绍一款强大而易用的Git客户端—…...
最新GPT4.0使用教程,AI绘画,ChatFile文档对话总结+GPT语音对话使用,DALL-E3文生图
一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画,文档对话总结DALL-E3文生图,相信对大家应该不感到陌生吧?简单来说,GPT-4技术比之前的GPT-3.5相对来说更加智能,会根据用户的要求生成多种内容甚至也可以和…...
【ARM 嵌入式 编译系列 7.2 -- GCC 链接脚本中 DEFINED 函数与 “AT>“ 符号详细介绍】
文章目录 GCC 链接脚本中 DEFINED 函数DEFINED() 函数> (放置在哪个区域)AT> (加载地址) (填充字节) 在链接脚本中,组合示例 GCC 链接脚本中 DEFINED 函数 在 ARM GCC 链接脚本(.ld 文件)中,DEFINED() 是一种内置函数&…...
Linux基础——进程初识(二)
1. 对当前目录创建文件的理解 我们知道在创建一个文件时,它会被默认创建到当前目录下,那么它是如何知道当前目录的呢? 对于下面这样一段代码 #include <stdio.h> #include <unistd.h>int main() {fopen("tmp.txt", …...
国科大图像处理2024速通期末——汇总2017-2019、2023回忆
国科大2023.12.28图像处理0854期末重点 图像处理 王伟强 作业 课件 资料 一、填空 一个阴极射线管它的输入与输出满足 s r 2 sr^{2} sr2,这将使得显示系统产生比希望的效果更暗的图像,此时伽马校正通常在信号进入显示器前被进行预处理,令p…...
编程笔记 html5cssjs 026 HTML输入类型(2/2)
编程笔记 html5&css&js 026 HTML输入类型(2/2) 输入类型:date输入类型:color输入类型:range输入类型:month输入类型:week输入类型:time输入类型:datetime输入类型…...
Vue2 - 数据响应式原理
目录 1,总览2,Observer3,Dep4,Watcher5,Schedule 1,总览 vue2官网参考 简单介绍下上图流程:以 Data 为中心来说, Vue 会将传递给 Vue 实例的 data 选项(普通 js 对象&a…...
网上代做论文的网站好/优化系统的软件
在当今的智能手机市场,iPhone和安卓形成了两大操作系统阵营,但是由于两者的操作系统不同、用户群体不同,导致使用手机的时候形成了不同的使用习惯,今天小胖就来总结一下两者在使用手机时的一些区别。清后台因为早年的安卓手机性能…...
做网站接广告赚钱吗/广东seo推广公司
什么是Css Selector? Css Selector定位实际就是HTML的Css选择器的标签定位 工具 Css Selector的练习建议大家安装火狐浏览器后,下载插件,FireFinder 或 FireBug和FirePath组合使用。 Css Selector使用方法 1、Css Selector支持ID、Class的定位…...
新闻系统网站开发dw实训总结报告/seo网页优化培训
一、fiddler接口压测 1)浏览器打开需要测试的url,可以看到url被fiddler拦截到,并出现在列表中。 2)在拦截到的url上点击鼠标右键,->replay -> shiftreissue request 设置访问次数,比如100 二、Compos…...
做网站卖东西赚钱么/百度导航怎么下载
PHP的网站主要攻击方式: 1、命令注入(Command Injection)2、eval注入(Eval Injection)3、客户端脚本攻击(Script Insertion)4、跨网站脚本攻击(Cross Site Scripting, XSS)5、SQL注入攻击(SQL injection)6、跨网站请求伪造攻击(Cross Site Request Forgeries, CSRF)…...
如何租用服务器做网站/长安seo排名优化培训
MPI简介在程序中,不同的进程需要相互的数据交换,特别是在科学计算中,需要大规模的计算与数据交换,集群可以很好解决单节点计算力不足的问题,但在集群中大规模的数据交换是很耗费时间的,因此需要一种在多节点…...
找人做网站需要注意什么问题/百度帐号登录入口
给出如下结构体,要求全部在堆区开辟空间。有多个老师,每个老师有多个学生。 typedef struct {char *name;//老师int stu_num;//学生数char **stu_arr;//学生名字 }TEACHER; 需要注意以下问题: 此问题使用双层循环即可解决。外层循环处理这…...