SpringBoot项目集成发邮件功能
- 1:引入依赖
- 2:配置设置
- 3:授权码获取:
- 4:核心代码
- 5:postman模拟验证
- 6:安全注意
1:引入依赖
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-email</artifactId><version>1.5</version></dependency>
2:配置设置
#邮箱配置
#平台地址,这里用的是qq邮箱,使用其他邮箱请更换
spring.mail.host = smtp.qq.com
#改成自己的邮箱
spring.mail.username = 1055560665@qq.com
#发送短信后它给你的授权码。填写你自己授权码
spring.mail.password =********
spring.mail.properties.mail.smtp.ssl.enable=true
##编码格式
spring.mail.default-encoding=UTF-8
3:授权码获取:

4:核心代码
package com.example.demo.controller;
import com.sun.org.apache.xml.internal.utils.SerializableLocatorImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
import java.util.Random;@RespController
@RequestMapping("/email")
public class emailController implements Serializable {@Autowiredprivate JavaMailSender mailSender;@Value("${spring.mail.username}")private String myemail;@RequestMapping("/sendcode")public boolean sendMimeMail(String useremail, HttpSession session) {try {SimpleMailMessage mailMessage = new SimpleMailMessage();mailMessage.setSubject("博客之站:验证码邮件");//主题//生成随机数String code = randomCode();//这里存在Session再放到redis或者内存;我就能验证了。HttpSession session = request.getSession();//不能让别人连续发送if(null!=session.getAttribute("code")){return Result.fail(-1,"发送过于频繁;请稍后再试");}//你得在验证码验证后/超过时间后;把Session的code设置为null//将随机数放置到session中//session.setAttribute("email", useremail);session.setAttribute("code", code);mailMessage.setText("您的验证码是:" + code);//内容mailMessage.setTo(useremail);//发给谁mailMessage.setFrom(myemail);//你自己的邮箱mailSender.send(mailMessage);//发送return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 随机生成6位数的验证码** @return String code*/public String randomCode() {StringBuilder str = new StringBuilder();Random random = new Random();for (int i = 0; i < 6; i++) {str.append(random.nextInt(10));}return str.toString();}}
5:postman模拟验证

6:安全注意
1:邮箱验证码得设置过期时间。Session的value是可以为null的
推荐思路:可以开启一个线程;在发送邮箱后阻塞2分半后把Session里的邮箱验证码code设置为null。或者定时器到这个时间后就这些这个任务。
2:邮箱码验证通过后也得进行清空操作
也是把Session里的邮箱验证码code设置为null即可。或者是删除掉session.removeAttribute(“code”);
3:虽然我们能在前端设置按钮只能点击一次邮箱然后恢复使用;但是如果像上述的postman模拟请求那不是能一直给你发邮件了?(写代码这些特殊情况一定得考虑;因为谁的可以给你发请求)
思路:每一次发送邮件的时候;我们可以取Session的验证码;如果是null我才能发邮件(我们上述操作会把失效/过期验证码这个设置为null)。否则发送失败。
相关文章:
SpringBoot项目集成发邮件功能
1:引入依赖2:配置设置3:授权码获取:4:核心代码5:postman模拟验证6:安全注意 1:引入依赖 <dependency><groupId>org.apache.commons</groupId><artifactId>c…...
【Spring篇】使用注解进行开发
🎊专栏【Spring】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【如愿】 🥰欢迎并且感谢大家指出小吉的问题 文章目录 🌺原代码(无注解)🎄加上注解⭐两个注…...
Flink(六)【DataFrame 转换算子(下)】
前言 今天学习剩下的转换算子:分区、分流、合流。 每天出来自学是一件孤独又充实的事情,希望多年以后回望自己的大学生活,不会因为自己的懒惰与懈怠而悔恨。 回答之所以起到了作用,原因是他们自己很努力。 …...
【2023春李宏毅机器学习】生成式学习的两种策略
文章目录 1 各个击破2 一步到位3 两种策略的对比 生成式学习的两种策略:各个击破、一步到位 对于文本生成:把每一个生成的元素称为token,中文当中token指的是字,英文中的token指的是word piece。比如对于unbreakable,他…...
Android13 adb 无法连接?
Android13 adb 无法连接? 文章目录 Android13 adb 无法连接?一、前言二、替换adbGoogle 官网对adb的介绍:Google 提供的adb tools的下载: 三、总结1、adb connect 连接后显示offline2、输入adb devices 报错:版本不匹配导致3、adb常用命令4…...
Ubuntu 20.04 调整交换分区大小
Ubuntu 调整交换分区大小 一、系统情况二、去除旧的交换分区文件三、配置并启用交换分区四、查看swap文件大小 一、系统情况 Ubuntu :Ubuntu 20.04.6 LTS 交换分区位置: cat /proc/swaps二、去除旧的交换分区文件 去掉旧的交换分区有两个步骤&#x…...
将Agent技术的灵活性引入RPA,清华等发布自动化智能体ProAgent
近日,来自清华大学的研究人员联合面壁智能、中国人民大学、MIT、CMU 等机构共同发布了新一代流程自动化范式 “智能体流程自动化” Agentic Process Automation(APA),结合大模型智能体帮助人类进行工作流构建,并让智能…...
高济健康:数字化科技创新与新零售碰撞 助推医疗产业优化升级
近日,第六届中国国际进口博览会在上海圆满落幕,首次亮相的高济健康作为一家专注大健康领域的疾病和健康管理公司,在本届进博会上向业内外展示了围绕“15分钟步行健康生活圈”构建进行的全域数字化升级成果。高济健康通过数字化科技创新与新零…...
SystemVerilog学习 (5)——接口
一、概述 验证一个设计需要经过几个步骤: 生成输入激励捕获输出响应决定对错和衡量进度 但是,我们首先需要一个合适的测试平台,并将它连接到设计上。 测试平台包裹着设计,发送激励并且捕获设计的输出。测试平台组成了设计周围的“真实世界”,…...
vue3插槽的使用
什么是插槽 Vue 3 插槽(Slots)是一个强大的工具,用于在组件之间传递内容和逻辑。通过使用插槽,我们可以将子组件中的内容插入到父组件中的特定位置。本篇文章将总结 Vue 3 插槽的基本用法、特点以及使用场景。 基本用法 插槽分为…...
IPTABLES问题:DNAT下如何解决内网访问内部服务器问题
这个问题,困扰了我几年了,今天终于得到解决。 问题是这样的,在局域网内部有一台服务器,通过IPTABLES的网关提供对外服务,做过IPTABLES网关的人都知道,这很容易做到,只要在网关机器上写一个DNAT…...
异步任务线程池——最优雅的方式创建异步任务
对于刚刚从校园出来的菜鸡选手很容易写出自以为没问题的屎山代码,可是当上线后就会立即暴露出问题,这说到底还是基础不够扎实!只会背八股文,却不理解,面试头头是道,一旦落地就啥也不是。此处,抛…...
uniapp 跨页面传值及跨页面方法调用
uniapp 跨页面传值及跨页面方法调用 1、跨页面传值 使用全局方法监听uni.$emit、uni.$on、uni.$off 发布、监听、移除 methods: {addFun(){let data [1]uni.navigateBack({ // 返回上一页delta: 1})uni.$emit(successFun,{data}) // 传值} }监听页 onLoad() {uni.$on(succ…...
无线物理层安全大作业
这个标题很帅 Beamforming Optimization for Physical Layer Security in MISO Wireless NetworksProblem Stateme Beamforming Optimization for Physical Layer Security in MISO W…...
目标检测标注工具AutoDistill
引言 在快速发展的机器学习领域,有一个方面一直保持不变:繁琐和耗时的数据标注任务。无论是用于图像分类、目标检测还是语义分割,长期以来人工标记的数据集一直是监督学习的基础。 然而,由于一个创新性的工具 AutoDistill&#x…...
关于SPJ表的数据库作业
打字不易,且复制且珍惜 建表 use 库名;create table S( --供应商 SNO char(6) not null, SNAME char(10) not null, STATUS INT, CITY char(10), primary key(SNO));create table P( --零件 PNO char(6) not null, PNAME char(12)not null, COLOR char(4), WEIGHT…...
【Nacos】配置管理、微服务配置拉取、实现配置热更新、多环境配置
🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 Nacos 一、nacos实现配置管理1.1 统一配置管…...
HTML5学习系列之网页图像
HTML5学习系列之网页图像 前言定义图像定义流定义图标 总结 前言 学习记录 定义图像 标签可以直接把图像插入网页中。 <img src"xx" alt"xx"/>src:显示图像的URLalt:设置图像的替代文本height、width:图像的高度…...
go语言学习之旅之Go语言数据类型
学无止境,今天学习Go 语言数据类型 Go(或Golang)是一种静态类型语言,这意味着变量的数据类型必须显式声明,并且在运行时不能更改。以下是Go中的一些基本数据类型: 这里仅介绍最常用的类型 数值类型: int: …...
Day49 力扣单调栈 : 739. 每日温度 |496.下一个更大元素 I
Day49 力扣单调栈 : 739. 每日温度 |496.下一个更大元素 I 739. 每日温度第一印象看完题解的思路什么是单调栈?我的总结 实现中的苦难感悟代码 496.下一个更大元素 I第一印象看完题解的思路实现中的困难感悟代码 739. 每日温度 今天正式开始单调栈,这是…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...
