01.Redis实现发送验证码保存功能

学习目标:

提示:学习如何利用Redis来实现发送验证码功能


学习产出:

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

1. 准备pom环境

		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope><version>5.1.47</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.17</version></dependency>

2. 配置ThreadLocal和过滤器

public class UserHolder {private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();public static void saveUser(UserDTO user){tl.set(user);}public static UserDTO getUser(){return tl.get();}public static void removeUser(){tl.remove();}
}
@Configuration
public class MvcConfig implements WebMvcConfigurer {@Autowiredprivate StringRedisTemplate redis;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor(redis))//哪些请求放行不走过滤器.excludePathPatterns("/user/code","/user/login","/blog/hot","/shop/**","/shop-type/**","/voucher/**");}
}
---------------------------------------------
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {private StringRedisTemplate redis;public LoginInterceptor(StringRedisTemplate redis) {this.redis = redis;}//controller执行之前@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.获取请求头中的tokenString authorization = request.getHeader("authorization");if (StrUtil.isBlank(authorization)) {response.setStatus(401);return false;}//2.基于token获取Redis中的用户Map<Object, Object> userMap = redis.opsForHash().entries("login:token:" + authorization);//3.判断用户是否存在if (userMap.isEmpty()) {//4.不存在,拦截,401response.setStatus(401);return false;}//5.将查询到的Hash数据转换为Dto对象UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);//6.存在,保存信息到ThreadLocalUserHolder.saveUser(userDTO);//7.访问接口每次都会刷新token过期时间redis.expire("login:token:" + authorization,30,TimeUnit.MINUTES);//7.放行return true;}//渲染后返回给前台数据前@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//移除用户,避免内存泄露UserHolder.removeUser();}
}

3. Controller层:负责接收请求和向下分配

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Resourceprivate IUserService userService;/*** 发送手机验证码*/@PostMapping("code")public Result sendCode(@RequestParam("phone") String phone) {//调用Service层来实现具体逻辑return userService.sendCode(phone);}}

4. Service层:负责业务的处理逻辑

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {private static final ObjectMapper mapper = new ObjectMapper();@Resourceprivate StringRedisTemplate redis;@Overridepublic Result sendCode(String phone) {//1.校验手机号if (RegexUtils.isPhoneInvalid(phone)) {//2.如果不符合,返回错误信息return Result.fail("无效手机号");}//3.符合,生成验证码String code = RandomUtil.randomNumbers(6);//4.保存验证码到Redis中redis.opsForValue().set(USER_NICK_NAME_PREFIX + phone, code, 60, TimeUnit.SECONDS);//5.模拟发送验证码log.info("发送验证码为===> {}", code);//6.返回return Result.ok();}//通过手机号创建新用户private User createUserWithPhone(String phone) {//创建用户User user = new User();user.setPhone(phone);user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));save(user);return user;}
}

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

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

相关文章

QT生成可执行文件的步骤

QT生成可执行文件的步骤 第一步&#xff1a;debug为release&#xff0c;然后进行编译 第二步&#xff1a;添加QT生成必要的库 首先&#xff0c;建立一个新的文件夹&#xff0c;然后将Release中的可执行文件拷贝到新的文件夹中 然后&#xff0c;在新建文件夹中生成必要的库 …

flutter:二维码生成与读取

前言 这csdn真的是服了&#xff0c;图片里有个二维码就直接变成违规图片了。至于效果的话&#xff0c;自己运行一下看看吧。 生成 flutter中生成二维码可以使用 qr_flutter。 官方文档 https://pub-web.flutter-io.cn/packages/qr_flutter 安装 flutter pub add qr_flutt…

使用vue-grid-layout时 You may need an appropriate loader to handle this file type.

使用vue-grid-layout时 You may need an appropriate loader to handle this file type. node版本不匹配 我的node v14.16.0 vue-gride-layout 需要用 v 2.3.7的版本 卸载后重新安装即可

我的2048创作纪念日

目录 一、来龙去脉二、2048天前的今天三、2048天的收获四、2048天后的今天五、祝福 一、来龙去脉 今天是 2023 年 8 月 9 日&#xff0c;在咖啡馆浏览我的 CSDN 主页时&#xff0c;看到官方发来了一则私信&#xff1a; 二、2048天前的今天 提示&#xff1a;可以和大家分享最初…

Xilinx FPGA电源设计与注意事项

1 引言 随着半导体和芯片技术的飞速发展&#xff0c;现在的FPGA集成了越来越多的可配置逻辑资源、各种各样的外部总线接口以及丰富的内部RAM资源&#xff0c;使其在国防、医疗、消费电子等领域得到了越来越广泛的应用。当采用FPGA进行设计电路时&#xff0c;大多数FPGA对上电的…

【第一阶段】kotlin的函数

函数头 fun main() {getMethod("zhangsan",22) }//kotlin语言默认是public,kotlin更规范&#xff0c;先有输入&#xff08; getMethod(name:String,age:Int)&#xff09;再有输出(Int[返回值]) private fun getMethod(name:String,age:Int): Int{println("我叫…

Qt 使用QLabel的派生类实现QLabel的双击响应

1 介绍 在QLabel中没有双击等事件响应&#xff0c;需要构建其派生类&#xff0c;自定义信号(signals)、重载事件函数(event)&#xff0c;最后在Qwidget中使用connect链接即可&#xff0c;进而实现响应功能。 对于其余没有需求事件响应的QObject同样适用。 此外&#xff0c;该功…

近地面无人机植被定量遥感与生理参数反演技术

遥感&#xff08;RS-Remote Sensing&#xff09;——不接触物体本身&#xff0c;用传感器收集目标物的电磁波信息&#xff0c;经处理、分析后&#xff0c;识别目标物&#xff0c;揭示其几何、物理性质和相互关系及其变化规律的现代科学技术。 换言之&#xff0c;即是“遥远的感…

Redis的安装方法与基本操作

目录 前言 一、REDIS概述 二、REDIS安装 1、编译安装 2.yum安装 三、Redis的目录结构 四、基础命令解析 五、在一台服务器上启动多个redis 六、数据库的基本操作 &#xff08;一&#xff09;登录数据库 &#xff08;二&#xff09;基础命令 七、Redis持久化 &#xff08;一&…

【2.2】Java微服务:Hystrix的详解与使用

目录 分布式系统面临问题 Hystrix概念 Hystrix作用 降级 什么是降级 order服务导入Hystrix依赖&#xff08;简单判断原则&#xff1a;谁调用远程谁加&#xff09; 启动类添加注解 业务方法添加注解&#xff08;冒号里填回调方法名&#xff0c;回调方法返回兜底数据&…

【MySQL】内置函数

文章目录 一、日期函数1.1 日期函数的基本使用1.2 案例11.3 案例2 二、字符串函数三、数学函数四、其他函数 一、日期函数 1.1 日期函数的基本使用 获取当前日期与日期 mysql> select current_date(), current_time(); -------------------------------- | current_date()…

FANUC机器人SRVO-300机械手断裂故障报警原因分析及处理办法

FANUC机器人SRVO-300机械手断裂故障报警原因分析及处理办法 首先,我们查看报警说明书上的介绍: 总结:即在机械手断裂设置为无效时,机器人检测出了机械手断裂信号(不该有的信号,现在检测到了,所以报警) 使机械手断裂设定为无效/有效的具体方法:  按下示教器的MENU菜单…

【LeetCode】数据结构题解(12)[用栈实现队列]

用栈实现队列 &#x1f609; 1.题目来源&#x1f440;2.题目描述&#x1f914;3.解题思路&#x1f973;4.代码展示 所属专栏&#xff1a;玩转数据结构题型❤️ &#x1f680; >博主首页&#xff1a;初阳785❤️ &#x1f680; >代码托管&#xff1a;chuyang785❤️ &…

爆肝整理,Postman接口测试-参数关联实战(详细步骤)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口测试什么时候…

Flink源码之JobManager启动流程

从启动命令flink-daemon.sh中可以看出StandaloneSession入口类为org.apache.flink.runtime.entrypoint.StandaloneSessionClusterEntrypoint, 从该类的main方法会进入ClusterEntrypoint::runCluster中, 该方法中会创建出主要服务和组件。 StandaloneSessionClusterEntrypoint:…

tomcat

文章目录 启动目录结构部署原始配置方式一方式二 在idea里配置注解配置 Servlet的执行流程生命周期相关信息其他配置request的各种方法访问页面 启动 下载->bin->点击startup.bat->启动 startup.sh 是Linux下的启动 注意&#xff1a; 需要是配java环境变量 目录结构…

Wav2Lip实践

1. 安装 1.1 安装 conda以指定python版本运行环境 下载&#xff1a;Index of /https://repo.anaconda.com/archive/index.html 1.2 如按旧项目基于python3.6版本对话&#xff0c;会有很多包找不到的情况&#xff0c;经摸索后以python3.9构建成功&#xff0c; conda instal…

IL汇编 ldarg 指令学习

IL汇编代码&#xff0c; .assembly extern mscorlib {} .assembly MathLib {.ver 1 : 0 : 1 : 0 }.module MathLib.dll.namespace MyMath { .class public ansi auto MathClass extends [mscorlib]System.Object{ .method public int32 GetSquare(int32) c…

C++进阶 智能指针

本篇博客简介&#xff1a;介绍C中的智能指针 智能指针 为什么会存在智能指针内存泄露内存泄漏定义内存泄漏的危害如何检测内存泄漏如何避免内存泄漏 智能指针的使用及其原理RAII设计一个智能指针C官方的智能指针 定制删除器智能指针总结 为什么会存在智能指针 我们首先来看下面…

Linux常见命令

新建标签页 (gitee.com)尹相辉 (yinxianghui66) - Gitee.com新建标签页 (gitee.com) 文章目录 文章目录 一、Linux常见命令 1.ls 2.cd 目录名 3.pwd 4.touch 文件名 5.echo 字符串->目标文件 6.cat 文件名 7.man 8.vim 文件名 9.mkdir 目录名 10.rm 文件名 11.mv 源…