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

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层:负责业务的处理逻辑

package com.hmdp.service.impl;import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hmdp.dto.LoginFormDTO;
import com.hmdp.dto.Result;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.User;
import com.hmdp.mapper.UserMapper;
import com.hmdp.service.IUserService;
import com.hmdp.utils.RegexUtils;
import com.hmdp.utils.SystemConstants;
import com.hmdp.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.xml.validation.Validator;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;import static com.hmdp.utils.RedisConstants.*;
import static com.hmdp.utils.SystemConstants.USER_NICK_NAME_PREFIX;/*** <p>* 服务实现类* </p>** @author 虎哥* @since 2021-12-22*/
@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.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;}
}

相关文章:

01.Redis实现发送验证码

学习目标&#xff1a; 提示&#xff1a;学习如何利用Redis来实现发送验证码功能 学习产出&#xff1a; 1. 准备pom环境 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><…...

Vue中对组件的调用

在Vue中&#xff0c;你可以在一个页面中调用其他组件&#xff0c;以实现组件的复用和组合效果。以下是在Vue中实现调用页面组件的几种常见方法之一&#xff1a; 1.使用Vue的组件标签&#xff1a; 你可以在Vue的模板中使用已注册的组件标签&#xff0c;以调用和渲染其他组件。首…...

SpringCloud Gateway获取请求响应body大小

前提 本文获取请求、响应body大小方法的前提 : 网关只做转发逻辑&#xff0c;不修改请求、相应的body内容。 SpringCloud Gateway内部的机制类似下图&#xff0c;HttpServer&#xff08;也就是NettyServer&#xff09;接收外部的请求&#xff0c;在Gateway内部请求将会通过Htt…...

二叉树的层序遍历

给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09; 。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]示例 2&#xff1a; 输入…...

Spring Boot 集成 Thymeleaf 模板引擎

Spring Boot 集成 Thymeleaf 模板引擎 1. Thymeleaf 介绍 Thymeleaf 是适用于 Web 和独立环境的现代服务器端 Java 模板引擎。 Thymeleaf 的主要目标是为开发工作流程带来优雅的自然模板&#xff0c;既可以在浏览器中正确显示的 HTML&#xff0c;也可以用作静态原型&#xff…...

如何快速找到合适的工作?

前面好几篇文章都在写面试的感悟&#xff0c;带大家了解了目前的一些市场行情&#xff0c;以及面试过程中招聘方与求职者看待面试的不同视角。 今天这篇文章写一些对大家求职面试可能更有用的几条建议&#xff1a; 第一&#xff0c;值与量的权衡 在早些年&#xff0c;大多数…...

Elasticsearch入门用例

快速开始 使用版本&#xff1a;V7.12 资料来自官方文档 本指南幫助初學者學習如何&#xff1a; 將數據添加到 Elasticsearch 搜索和排序數據 在搜索過程中從非結構化內容中提取字段 测试运行&#xff1a; http://localhost:9200 响应&#xff1a; {"name": &qu…...

python制作超炫流星雨表白,python好看的流星雨代码

大家好&#xff0c;本文将围绕python制作超炫流星雨表白展开说明&#xff0c;python好看的流星雨代码是一个很多人都想弄明白的事情&#xff0c;想搞清楚html流星雨代码可复制需要先了解以下几个事情。 本文讲述了Python代码示例&#xff1a;实现流星雨特效&#xff01;具有很好…...

iOS数字转为图片

根据数字&#xff0c;转成对应的图片 - (void)viewDidLoad {[super viewDidLoad];[self testNum2String:10086]; }/// 根据数字&#xff0c;显示对应的图片 数字用特定的图片显示 - (void)testNum2String:(NSInteger)num {UIView *numContentView [[UIView alloc] initWithFr…...

mac cli文件管理器

背景 最近研究了一下在控制台查看文件的插件ranger, 官方的解释是&#xff1a;一个cli下的文件管理器。觉得效果也很酷炫&#xff0c;所以在此展示一下。 安装 brew install ranger配置生成 建议第一次使用的时候使用 ranger --copy-configall将会在~/.config/ranger目录输…...

不同语言操作符的优先级

看到标题&#xff0c;可能会心生疑惑: 这么基础且重要的操作&#xff0c;不同语言不应该是一致的吗&#xff1f; 并不一定&#xff0c;比如对于右移运算和加法运算&#xff0c;Go就与其他多数语言表现得不一致&#xff1a; Go: package mainimport "fmt"func main() …...

YOLOv5源码解读1.7-网络架构common.py

往期回顾:YOLOv5源码解读1.0-目录_汉卿HanQ的博客-CSDN博客 学习了yolo.py网络模型后&#xff0c;今天学习common.py&#xff0c;common.py存放这YOLOv5网络搭建的通用模块&#xff0c;如果修改某一块&#xff0c;就要修改这个文件中对应的模块 目录 1.导入python包 2.加载自…...

关于前端框架vue2升级为vue3的相关说明

一些框架需要升级 当前&#xff08;202306&#xff09; Vue 的最新稳定版本是 v3.3.4。Vue 框架升级为最新的3.0版本&#xff0c;涉及的相关依赖变更有&#xff1a; 前提条件&#xff1a;已安装 16.0 或更高版本的Node.js&#xff08;摘&#xff09; 必须的变更&#xff1a;核…...

gdb调试时查看汇编代码

在gdb中查看汇编代码&#xff0c;可以使用display命令或x命令。 以下是一个示例程序&#xff0c;我们以它为例来演示如何在gdb中查看汇编代码。 #include <stdio.h> int main() { int a 10; int b 20; int c a b; printf("c %d\n", c); return 0;…...

小研究 - JVM GC 对 IMS HSS 延迟分析(二)

用户归属服务器&#xff08;IMS HSS&#xff09;是下一代通信网&#xff08;NGN&#xff09;核心网络 IP 多媒体子系统&#xff08;IMS&#xff09;中的主要用户数据库。IMS HSS 中存储用户的配置文件&#xff0c;可执行用户的身份验证和授权&#xff0c;并提供对呼叫控制服务器…...

eNSP 路由器启动时一直显示 # 号的解决办法

文章目录 1 问题截图2 解决办法2.1 办法一&#xff1a;排除防火墙原因导致 3 验证是否成功 1 问题截图 路由器命令行一直显示 # 号&#xff0c;如下图 2 解决办法 2.1 办法一&#xff1a;排除防火墙原因导致 排查是否因为系统防火墙原因导致。放行与 eNSP 和 virtualbox 相…...

Kotlin~Facade

概念 又称门面模式&#xff0c;为复杂系统提供简单交互接口。 角色介绍 Facade&#xff1a;外观类&#xff0c;供客户端调用&#xff0c;将请求委派给响应的子系统。SubSystem&#xff1a;子系统&#xff0c;独立的子设备或子类 UML 代码实现 class Light(val name: Strin…...

服务配置文件/var/lib/systemd与/etc/systemd/

这两个目录都是用于存储 systemd 服务的配置文件。但它们的作用和用途略有不同。 /etc/systemd/system/: 这个目录存放的是系统管理员自己创建或修改的 systemd 服务配置文件。在这里的配置文件优先级更高&#xff0c;会覆盖默认的 systemd 配置文件。通常&#xff0c;我们可以…...

华为、阿里巴巴、字节跳动 100+ Python 面试问题总结(一)

系列文章目录 个人简介&#xff1a;机电专业在读研究生&#xff0c;CSDN内容合伙人&#xff0c;博主个人首页 Python面试专栏&#xff1a;《Python面试》此专栏面向准备面试的2024届毕业生。欢迎阅读&#xff0c;一起进步&#xff01;&#x1f31f;&#x1f31f;&#x1f31f; …...

【牛客网】二叉搜索树与双向链表

二叉搜索树与双向链表 题目描述算法分析编程代码 链接: 二叉搜索树与双向链表 题目描述 算法分析 编程代码 /* struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {} };*/ class Solution { public:…...

突破Windows资源管理器性能瓶颈:智能缩略图预加载解决方案

突破Windows资源管理器性能瓶颈&#xff1a;智能缩略图预加载解决方案 【免费下载链接】WinThumbsPreloader-V2 WinThumbsPreloader is a powerful open source tool for quickly preloading thumbnails in Windows Explorer. 项目地址: https://gitcode.com/gh_mirrors/wi/W…...

ATxmega时钟与GPIO配置详解:从原理到实战调试

1. 项目概述&#xff1a;从零认识ATxmage的时钟与GPIO最近在捣鼓一块ATxmage的开发板&#xff0c;很多刚入门的朋友拿到手&#xff0c;面对密密麻麻的引脚和一堆陌生的寄存器&#xff0c;往往不知道从哪里下手。其实&#xff0c;玩转任何一款微控制器&#xff0c;最核心、最基础…...

深入UE渲染管线:从.usf文件到FGlobalShader,理解全局Shader的完整生命周期与最佳实践

深入UE渲染管线&#xff1a;从.usf文件到FGlobalShader&#xff0c;理解全局Shader的完整生命周期与最佳实践 当我们需要在Unreal Engine中实现一个全新的后处理效果或定制底层渲染管线时&#xff0c;全局Shader&#xff08;Global Shader&#xff09;往往是必经之路。与材质编…...

Excel数据导入实战:为缺失ID列批量生成标准UUID

1. 为什么需要为Excel数据批量生成UUID&#xff1f; 最近在处理一个数据迁移项目时&#xff0c;遇到了一个典型问题&#xff1a;从Navicat导出的Excel表格缺少主键列&#xff0c;导致后续数据导入时频频报错。这种情况在数据迁移、系统对接时特别常见。UUID&#xff08;通用唯…...

FreeRDP 终极指南:跨平台远程桌面完全解决方案

FreeRDP 终极指南&#xff1a;跨平台远程桌面完全解决方案 【免费下载链接】FreeRDP FreeRDP is a free remote desktop protocol library and clients 项目地址: https://gitcode.com/gh_mirrors/fr/FreeRDP FreeRDP 是一款功能强大的开源远程桌面协议实现库&#xff0…...

观察Taotoken用量看板如何帮助团队精打细算每一分token

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 观察Taotoken用量看板如何帮助团队精打细算每一分token 对于依赖大模型进行开发的团队而言&#xff0c;成本控制与预算规划是日常运…...

Qt C++ 集成 SQLite 实现本地数据持久化:从原理到宠物投喂器实战

1. 项目概述与核心需求解析最近在做一个宠物智能投喂器的数据管理后台&#xff0c;核心需求是把设备上传的各种运行数据持久化存储起来&#xff0c;方便后续分析和查看。设备会上传投喂间隔时间、水温、剩余重量这几个关键参数&#xff0c;我需要一个轻量、可靠且易于集成的本地…...

RimSort终极指南:开源跨平台RimWorld模组管理器完全解析

RimSort终极指南&#xff1a;开源跨平台RimWorld模组管理器完全解析 【免费下载链接】RimSort RimSort is an open source mod manager for the video game RimWorld. There is support for Linux, Mac, and Windows, built from the ground up to be a reliable, community-ma…...

Beyond Compare 5密钥生成终极指南:从激活失败到完全使用

Beyond Compare 5密钥生成终极指南&#xff1a;从激活失败到完全使用 【免费下载链接】BCompare_Keygen Keygen for BCompare 5 项目地址: https://gitcode.com/gh_mirrors/bc/BCompare_Keygen 你是否也遇到过Beyond Compare 5弹出"评估模式错误"的困扰&#…...

SPI接口技术解析与Keil开发实践指南

1. SPI接口技术解析与应用指南作为一名嵌入式开发工程师&#xff0c;我经常需要与各种外设进行通信&#xff0c;而SPI&#xff08;Serial Peripheral Interface&#xff09;无疑是最常用的串行通信协议之一。今天我想分享一些关于SPI接口的实用知识和资源&#xff0c;这些内容来…...