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

2024-06-23 23:04

本文主要是介绍实际项目开发:Spring集成Redis,并实现短信登录功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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 {@Autowiredprivate 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类:包含验证码、手机号,为了方便接收前端的数据,现在验证码属性为nullString 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);}// 不相同,则返回nullreturn PublicDataDTO.getPublicDataDTO(null);}

八、效果演示

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

九、结语

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

这篇关于实际项目开发:Spring集成Redis,并实现短信登录功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1088529

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

Java五子棋之坐标校正

上篇针对了Java项目中的解构思维,在这篇内容中我们不妨从整体项目中拆解拿出一个非常重要的五子棋逻辑实现:坐标校正,我们如何使漫无目的鼠标点击变得有序化和可控化呢? 目录 一、从鼠标监听到获取坐标 1.MouseListener和MouseAdapter 2.mousePressed方法 二、坐标校正的具体实现方法 1.关于fillOval方法 2.坐标获取 3.坐标转换 4.坐

Spring Cloud:构建分布式系统的利器

引言 在当今的云计算和微服务架构时代,构建高效、可靠的分布式系统成为软件开发的重要任务。Spring Cloud 提供了一套完整的解决方案,帮助开发者快速构建分布式系统中的一些常见模式(例如配置管理、服务发现、断路器等)。本文将探讨 Spring Cloud 的定义、核心组件、应用场景以及未来的发展趋势。 什么是 Spring Cloud Spring Cloud 是一个基于 Spring

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

java8的新特性之一(Java Lambda表达式)

1:Java8的新特性 Lambda 表达式: 允许以更简洁的方式表示匿名函数(或称为闭包)。可以将Lambda表达式作为参数传递给方法或赋值给函数式接口类型的变量。 Stream API: 提供了一种处理集合数据的流式处理方式,支持函数式编程风格。 允许以声明性方式处理数据集合(如List、Set等)。提供了一系列操作,如map、filter、reduce等,以支持复杂的查询和转

用Microsoft.Extensions.Hosting 管理WPF项目.

首先引入必要的包: <ItemGroup><PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" /><PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /><PackageReference Include="Serilog

Java面试八股之怎么通过Java程序判断JVM是32位还是64位

怎么通过Java程序判断JVM是32位还是64位 可以通过Java程序内部检查系统属性来判断当前运行的JVM是32位还是64位。以下是一个简单的方法: public class JvmBitCheck {public static void main(String[] args) {String arch = System.getProperty("os.arch");String dataM

详细分析Springmvc中的@ModelAttribute基本知识(附Demo)

目录 前言1. 注解用法1.1 方法参数1.2 方法1.3 类 2. 注解场景2.1 表单参数2.2 AJAX请求2.3 文件上传 3. 实战4. 总结 前言 将请求参数绑定到模型对象上,或者在请求处理之前添加模型属性 可以在方法参数、方法或者类上使用 一般适用这几种场景: 表单处理:通过 @ModelAttribute 将表单数据绑定到模型对象上预处理逻辑:在请求处理之前

eclipse运行springboot项目,找不到主类

解决办法尝试了很多种,下载sts压缩包行不通。最后解决办法如图: help--->Eclipse Marketplace--->Popular--->找到Spring Tools 3---->Installed。

JAVA读取MongoDB中的二进制图片并显示在页面上

1:Jsp页面: <td><img src="${ctx}/mongoImg/show"></td> 2:xml配置: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001