实际项目开发:Spring集成Redis,并实现短信登录功能

news2024/11/17 17:31:49

redis新手,学了几种基本数据类型,却不知道怎么使用?
总是一边学一边忘?
学会了Redis的大多数使用命令,却不知道如何在项目中使用?
本文将从实际出发,为大家解决这些问题。
我是蚊子码农,欢迎各位的点赞、关注和收藏,有了你们的激励,我会带来更好的作品。

一、环境准备

从环境出发。

第一,基础环境:
  1. JDK版本:JDK1.8。
  2. 构建工具:Maven。
  3. 开发工具:IDEA。
  4. 基础依赖:SpringBoot通用依赖。
  5. 前后端验证机制:JWT令牌机制【如果是Token,可以看成一样;如果是cookie或session,则需要按情况改变】
第二,个人环境:
  1. Redis环境(操作系统):Windows10
  2. 使用的Redis客户端:lettuce

二、在pom文件导入Redis的相关依赖、配置Redis相关信息

注意:本文的基础,是已经安装好Redis,并且学会启动Redis服务器的用户。
简要安装步骤:来到Redis官网,按照版本下载—》解压Redis的压缩包到某个目录—》在这个解压包里,找到redis-server.exe打开服务器。【这个方法的好处是,不用配置系统变量,当然,也不能随时随地通过CMD命令启动Redis】

        <!--    redis的依赖    -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.11.1</version>

完成依赖的导入后,需要配置appliacation.yml文件的配置信息。
这个信息和MySQL非常类似,如下:

  redis:
    host: 127.0.0.1 # 服务器的IP地址
    port: 6379 # 默认端口号
    # 默认密码是null,如果设定密码则修改
    password: 
	# lettuce客户端
    lettuce:
      # 连接池的配置信息,和线程池类似
      pool:
        max-active: 8   # 最大连接数,负数表示无限制
        max-wait: -1    # 最大阻塞等待时间,负数则表示无限制
        max-idle: 8     # 连接池最大空闲连接

三、写Redis操作的通用类RedisUtil【基于StringRedisTemplate类】

在Spring集成Redis的项目中,通常可以使用RedisTemplate和StringRedisTemplate来操作Redis。
RedisTemplate<K, V>,是一个泛型类,允许很多种结构,灵活性很高。
而StringRedisTemplate<String, String>,继承自RedisTemplate,只允许字符串对字符串的映射,相对来说灵活性较差,但是开发字符串结构的业务,非常方便高效。
本文的短信验证机制,只需要String对String即可,因此,使用StringRedisTemplate开发。
工具类代码如下,本质只有读、写两个操作:

// 可以写接口和实现类,来充分解耦,本文不解耦
@Component
public class RedisUtil {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    // 向Redis中,设定验证码【手机号映射code的方式】
    public void redisSetCode(String phone, String code){
	// 设定手机号、验证码、5分钟的过期时间【最后的参数,是时间单位】
        stringRedisTemplate.opsForValue().set(phone, code, 60 * 5, TimeUnit.SECONDS);
    }
    
    // 从Redis中得到验证码,如果返回null,表示没有这个phone,在此不做验证
    public String redisGetCode(String phone){
        return stringRedisTemplate.opsForValue().get(phone);
    }
}

四、短信登陆功能的开发步骤

短信登录验证是市面上最火的登录验证方式之一。
从B/S的交互角度来看,它一共有4步:

第一,用户输入手机号,并向服务器发送请求。
第二,服务器验证手机号有效性,生成验证码,并将验证码返回客户端。
第三,用户输入手机号、验证码,并向服务器发送请求。
第四,服务器验证二者的对应关系和有效性,返回结果。

我们可以发现,这个验证机制的关键只有2个,手机号、验证码。
二者有一对一的关系,为了保证安全,验证码还必须有过期策略。因此,在没有其它业务逻辑的情况下,可以使用redis方便地完成这个功能。
不使用MySQL的原因:该验证机制较为简单,使用MySQL却需要建立一张难以变化的表,很不值得,加上访问速度也没有Redis快。
本文面向后端用户,所以前端的开发流程在此不说明,我们重点关注以下步骤:

第一,得到手机号。

这一步,需要做至少3件事:

  1. 手机号有效性检测【判断数据库有没有这个人(如果该验证机制,不允许使用手机号注册的话)】
  2. 生成验证码
  3. 将验证码写进Redis
  4. 注:借用短信API将验证码发给用户。【这一步不好写】
第二,得到手机号、验证码

需要做2件事:

  1. 判断手机号与验证码是否对应
  2. 如果对应,返回个人信息;如果不对应,报错。

五、后端得到手机号

在开发前,我们要保证,前端传来的手机号没有异常。【在本文不判断手机号null的情况】

第一步,搜索数据库,查找有没有这个人

说明:这一步可以省略,可以直接返回验证码,等到用户拿到验证码后,再从数据库拿数据判断,这样可以节省一点后端资源。【不过,用户使用起来是比较难受的,所以建议先判断】
判断的代码比较简单,在此不说明。

第二步,生成验证码

这个业务,可能需要各种复用,干脆写成一个工具类。
代码如下:

public class GeneCodeUtil {
    // 验证码的范围,如果想使用复杂字符,可以写i、g、a、b等
    public static final String VERIFY_CODES = "1234567890";

	// 验证码生成函数,指定验证码的位数【比如4位验证码:1234、5144】
    public static String CodeGenerate(int verifySize){
        String sources = VERIFY_CODES;
        int codesLen = sources.length();
		// 以当前的毫秒数为种子,生成随机数
        Random rand = new Random(System.currentTimeMillis());
	
		// 使用StringBuilder结构存储数据
        StringBuilder sb = new StringBuilder(verifySize);
        for(int i = 0; i < verifySize; i++){
        	// 添加到sb里
            sb.append(sources.charAt(rand.nextInt(codesLen-1)));
        }
        return sb.toString();
    }
}
第三,将手机号、验证码写入Redis数据库。

由于我们已经写好了Redis的工具类,在此调用工具类的set方法即可。
下面的代码,是手机号发送的业务逻辑:
下面的一些类,比较简单,就不分开讲解了,我都在第一次使用时,做了说明

	// 验证有效性,生成验证码,写入Redis数据库
    @PostMapping("/login")
    public CodeDTO loginGenerateCode(@RequestBody PhoneCodeDTO phoneCodeDTO){
    	// CodeDTO类:包含通用的返回信息、返回状态码;比如【1,验证码成功发送】
		// PhoneCodeDTO类:包含验证码、手机号,为了方便接收前端的数据,现在验证码属性为null

        String phone = phoneCodeDTO.getPhone();        
		// 查找有没有这个人
        String tempPhone = new String(phone);
        // Public类:一个数据类,不重要
        LambdaQueryWrapper<Public> publicLambdaQueryWrapper = new LambdaQueryWrapper<>();
        publicLambdaQueryWrapper.eq(Public::getPubNum,Long.parseLong(tempPhone));
		// 得到这个人
        Public pub = publicService.getOne(publicLambdaQueryWrapper);
		// 空表示没有,说明失败
        if(pub == null){
        	// codeFail:返回CodeDTO的对象,输入的数据,即为返回信息
            return CodeDTO.codeFail("不存在此用户");
        }

		// codeRedisAndSend:send函数做了2件事。。1.生成验证码;2.写入Redis服务器
        codeRedisAndSend.send(phone);
		// 可以在这里,写一些代码,调用信息发送API,将信息发送给用户

		// codeSuccess:返回CodeDTO对象,输入的数据为返回信息
        return CodeDTO.codeSuccess("验证码发送成功");
    }

六、阶段效果演示

使用Postman,发送请求给服务器
不存在用户时:
用户不存在时的展示
将该用户添加到数据库表中后:
验证码成功发布

七、后端拿到验证码、手机号

其实业务逻辑比较简单,所以直接看代码即可。

 	// 请求URL
    @RequestMapping("/codeLogin")
	// 效验验证码,如果有这个人,返回这个人的数据,JWT令牌
    public PublicDataDTO loginByCode(@RequestBody PhoneCodeDTO phoneCodeDTO){
        // PublicDataDTO类:包含用户信息、JWT令牌及一些附带信息
        // PhoneCodeDTO类:包含验证码、手机号信息
        
        String phone = phoneCodeDTO.getPhone();
		// 判断手机号、验证码是否对应,getCode方法是从Redis服务器拿到验证码
        if( phoneCodeDTO.getCode().equals(codeRedisAndSend.getCode(phone)) ){
             LambdaQueryWrapper<Public> publicLambdaQueryWrapper = new LambdaQueryWrapper<>();
             publicLambdaQueryWrapper.eq(Public::getPubNum,Long.parseLong(phone));
			// 得到此人信息
             Public pub = publicService.getOne(publicLambdaQueryWrapper);

			// getPublicDataDTO方法:返回一个PublicDataDTO对象
			// JWT令牌是JWT工具类生成的,传给前端,用作后续效验
             return PublicDataDTO.getPublicDataDTO(pub);
         }

		// 不相同,则返回null
         return PublicDataDTO.getPublicDataDTO(null);
    }

八、效果演示

同样使用Postman作为演示,假设我们知道验证码是1666
那么,输入错误的验证码:
错误验证码
我们输入正确的验证码
正确验证码

九、结语

我是蚊子码农,如有补充或者疑问,欢迎在评论区留言。个人的知识体系可能没有那么完善,希望各位多多指正,谢谢大家。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

gin-vue -admin 初始化安装后 进入 后台首页报错

报错原因&#xff1a; 因为 我是使用的phpstudy 小皮的数据库 默认的是MySam 的引擎 mysql 引擎需要是 innoDB 解决办法 &#xff1a; 在linux 的环境下 配置一个数据库 &#xff0c; 我是用的是vmware 虚拟机

【DC-DC升压电推剪方案】FP6277,FP6296电源升压芯片在电推剪中扮演着一个怎样的角色?带你深入了解电推剪的功能和应用及工作原理

随着人们对个人形象要求的不断提高&#xff0c;理发器作为一个必备的家居用品&#xff0c;也在不断进行技术升级。而其中的核心装备之一&#xff0c;电推剪理发器升压芯片FP6277、FP6296&#xff0c;正在引领着现代理发技术的突破。本文将给大家带来的是电推剪在传统意义上运用…

V-Series Avalon-MM DMA Interface for PCIE IP核

目录 1. IP概述 2. Avalon-MM DMA Ports 3. 参数设置 3.1 系统设置 3.2 基址寄存器 (BAR) 设置 3.3 设备识别寄存器 3.4 PCI Express和PCI功能参数 3.4.1 Device Capabilities 3.4.2 Error Reporting 3.4.3 Link Capabilities 3.4.4 MSI and MSI-X Capabilities …

开源 150 T 数据(2023年之前所有数据)

开源 150 T 数据&#xff08;2023年之前所有数据&#xff09; 开源 150 T 数据生成大规模、高质量训练数据集 生成巨量数据 数据清洗和过滤 混合数据源 多级别训练和模型评估 探索新的训练策略多级别训练和模型评估探索新的训练策略 万卡 H100 集群训练 开源 150 T 数据 …

B+树与索引解析

文章目录 B树与索引简介几个关键点应用案例场景描述索引创建查询操作更新操作并发处理 Python代码示例 B树与索引简介 B树是一种在计算机科学中广泛使用的自平衡的树数据结构&#xff0c;它能保持数据排序&#xff0c;并且搜索、插入和删除操作的时间复杂度都是O(log n)。B树被…

【Docker项目实战篇】Docker部署PDF多功能工具Stirling-PDF

【Docker项目实战篇】Docker部署PDF多功能工具Stirling-PDF 前言一、Stirling-PDF介绍1.1 Stirling-PDF简介1.2 Stirling-PDF功能 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四…

【AI原理解析】—朴素贝叶斯原理

朴素贝叶斯&#xff08;Naive Bayes&#xff09;是一种基于贝叶斯定理与特征条件独立假设的分类方法。这种分类方法简单、高效&#xff0c;并且在很多实际场景中都有良好的表现。 1. 贝叶斯定理 贝叶斯定理是关于条件概率的定理&#xff0c;它描述了两个条件概率之间的关系。…

shell (三)shell脚本

SHELL脚本 编程语言的分类 解释型语言&#xff1a;shell&#xff0c;Python&#xff0c;需要解析器 编译型语言&#xff1a;C语言&#xff0c;C&#xff0c;需要编译器 shell脚本 操作系统的结构 shell&#xff08;贝壳&#xff09; 应用层 app&#xff0c;代码 应用层需要通…

【项目实训】后端逻辑完善

经测试&#xff0c;我们决定前端可以同时选择多个类型的岗位进行查询&#xff0c;以显示相应的公司岗位信息 于是&#xff0c;修改后端函数的逻辑&#xff1a; 后端 首先&#xff0c;因为要对checkList中的job_name进行模糊匹配查询&#xff0c;于是使用以下代码&#xff1a…

C++之STL(九)

1、函数对象 什么适合推荐使用函数对象&#xff1f; 需要状态的函数调用: 需要状态的函数调用: 函数对象可以包含成员变量&#xff0c;可以在多次调用中保持状态。这在某些算法中非常有用。 提高性能: 编译器可以更好地优化函数对象&#xff0c;因为它们是具体的类型&#xf…

[Redis]主从模式

启动主从复制 由于我们只有一台机器&#xff0c;所以我们只能在机器上开多个redis程序来演示不同的机器 因为一个端口号只能被一个进程绑定&#xff0c;所以我们需要修改配置&#xff0c;绑定不同的端口号&#xff0c;并且还要修改工作目录&#xff08;数据持久化的位置&#…

ChatTTS源码部署

感谢阅读 默认已完成的操作准备工作下载源码安装依赖下载补丁(报错在运行) 界面展示(discord上有各种补丁&#xff0c;我的加了UI补丁和音色增强)提示词常用&#xff08;这个每个音基本都能生效&#xff09;语调类语速类情感类 默认已完成的操作 python版本>3.9 cuda版本的…

3D渲染时如何提高GPU的使用率?这7点告诉你

GPU 正逐渐取代 CPU 在 3D 渲染中的地位。我们看到许多 GPU 渲染器如 Redshift、Octane、FStorm 等不断推出。以前只支持 CPU 渲染的渲染器&#xff0c;如 Arnold、V-Ray、Renderman、Keyshot 等&#xff0c;现在也开始支持 GPU 渲染。实时渲染的发展使 GPU 更受欢迎&#xff0…

梗图生成器突然爆红;ElevenLabs发布IOS APP 高质量语音朗读手机各种文本内容;开源工作流架构ControlFlow

✨ 1: 梗图生成器 fabianstelzer 在Glif做的一个超强meme生成器 Glif 是一个工作流&#xff0c;能生成文字图片和视频&#xff0c;用工作流的形式可以完成很多的花样来。 最近爆红的梗图生成器&#xff0c;WOJAK MEME GENERATOR &#xff0c;也是用工作流的形式来生成这些有…

TiDB-从0到1-数据导出导入

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇TiDB-从0到1-配置篇TiDB-从0到1-集群扩缩容 一、数据导出 TiDB中通过Dumpling来实现数据导出&#xff0c;与MySQL中的mysqldump类似&#xff0c;其属于…

如何选择适合你的免费电子合同软件?八款工具深度对比

主流的8款免费合同软件包括&#xff1a;国内的e签宝、法大大、上上签、契约锁&#xff0c;以及国外的SignWell、PandaDoc、Signaturely、HelloSign和SignRequest。 随着技术的进步&#xff0c;尤其是区块链技术的应用&#xff0c;电子合同的安全性和可信度正在逐渐增强。这些技…

如何提取mac app中的应用程序图标 x.app图标位置

在macos系统中安装的应用程序 .app的图标都是 以 .icns结尾的&#xff0c;默认位于 .app应用程序包中的Contents/Resources/目录下&#xff0c;只要是在这个目录下的 .icns文件就是这个应用的图标&#xff0c;如&#xff1a;mac版微信的图标就是 /Applications/WeChat.app/Co…

5个顶级开源Agent框架,你必须知道!

进入2024年&#xff0c;人工智能的发展已经达到了前所未有的高度&#xff0c;尤其是在Agent框架这一领域&#xff0c;出现了几个引人注目的技术成果。这些框架在智能规划、用户体验增强、记忆处理、以及大型模型调用等方面有着卓越表现&#xff0c;对AI界的未来发展提供了值得期…

利用多模态大模型,构建自动驾驶场景检索解决方案 | 创新场景

ITValue 痛点 在自动驾驶数据闭环的业务场景中&#xff0c;企业面临的挑战是难以高效的从PB级的视频和图片中选取有价值的数据&#xff0c;以训练和优化自动驾驶算法。 解决方案 为解决该挑战&#xff0c;亚马逊云科技利用大语言模型和图像文本多模态嵌入空间架构&#xff0c;构…

CY5-NHS生物标记应用146368-14-1

在生物科学研究和技术应用领域&#xff0c;荧光标记技术已成为一种科研工具。其中&#xff0c;CY5-NHS以其荧光特性和标记能力&#xff0c;在生物标记应用中扮演着科研角色。 CY5-NHS的特性与优势 CY5-NHS是一种荧光标记试剂&#xff0c;其荧光基团CY5赋予其强烈的荧光信号和…