【未完成】springboot项目实现扫码登录相关逻辑
准备工作
配置redis
引入redis依赖
<dependencies><!-- Spring Data Redis 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Jedis 依赖 --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency>
</dependencies>
在application.yml中配置redis
spring:redis:host: 127.0.0.1port: 6379database: 0password:
配置 Jedis 连接池
@Component
@ConfigurationProperties(prefix = "spring.redis")
public class RedisConfigInfo {private String host;private Integer port;private Integer database;private String password;// 省略getter、setter方法
}
@Configuration
public class JedisConfig {@Autowiredprivate RedisConfigInfo redisConfigInfo;@Beanpublic JedisConnectionFactory jedisConnectionFactory() {RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();redisStandaloneConfiguration.setHostName(redisConfigInfo.getHost());redisStandaloneConfiguration.setPort(redisConfigInfo.getPort());String password = redisConfigInfo.getPassword();// 将字符串类型的密码转换为 RedisPassword 类型if (password != null && !password.isEmpty()) {redisStandaloneConfiguration.setPassword(RedisPassword.of(password));} else {redisStandaloneConfiguration.setPassword(RedisPassword.none());}redisStandaloneConfiguration.setDatabase(redisConfigInfo.getDatabase());return new JedisConnectionFactory(redisStandaloneConfiguration);}@Beanpublic RedisTemplate<String, Object> redisTemplate() {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(jedisConnectionFactory());// 设置键的序列化器为 StringRedisSerializertemplate.setKeySerializer(new StringRedisSerializer());// 设置哈希键的序列化器为 StringRedisSerializertemplate.setHashKeySerializer(new StringRedisSerializer());// 设置值的序列化器为 GenericJackson2JsonRedisSerializer,用于处理 JSON 数据template.setValueSerializer(new GenericJackson2JsonRedisSerializer());// 设置哈希值的序列化器为 GenericJackson2JsonRedisSerializertemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());return template;}
}
QrCodeController
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;@RestController
@RequestMapping("/qr-code")
public class QrCodeController {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;// 生成二维码的接口@GetMapping(value = "/generate", produces = MediaType.APPLICATION_JSON_VALUE)public ResponseEntity<Map<String, String>> generateQrCode() {// 生成一个唯一的登录请求标识符String token = UUID.randomUUID().toString();// 存储 token 到 Redis 并设置 5 分钟有效期redisTemplate.opsForValue().set(token, "valid", 5, TimeUnit.MINUTES);// 封装返回的 JSON 数据Map<String, String> response = new HashMap<>();response.put("token", token);return ResponseEntity.ok(response);}// APP 扫描二维码后调用的接口@PostMapping("/scan")public String scanQrCode(@RequestBody ScanRequestInfo scanRequestInfo) {String token = request.getToken();String userId = request.getUserId();Map<String, String> response = new HashMap<>();if ("valid".equal(redisTemplate.opsForValue().get(token))) {// 将查询到用户信息(主要是token)放入缓存redisTemplate.opsForValue().set(token, userId, 1, TimeUnit.MINUTES);response.put("code", 0);} else {response.put("code", -1);}return ResponseEntity.ok(response);}@GetMapping("/checkLoginStatus")public String checkLoginStatus(@RequestParam String token) {// 使用 RedisTemplate 从 Redis 中获取登录状态String userId = (Boolean) redisTemplate.opsForValue().get(token);Map<String, String> response = new HashMap<>();if (userId != null && "valid".equal(userId)) { // 根据userId查询用户信息并返回UserInfo userInfo = new UserInfo();response.put("code", 0);response.put("userInfo", userInfo);} else {response.put("code", -1);}return ResponseEntity.ok(response);}
}
UserInfo
@Data
public class UserInfo{private String userId;private String userName;private String token;
}
ScanRequestInfo
@Data
public class ScanRequestInfo{private String token;private String userId;
}
引入lombok依赖
<dependencies><!-- 引入 Lombok 依赖 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><!-- 可以根据需要调整版本号 --><version>1.18.26</version><!-- 对于编译和测试范围使用,运行时不需要 --><scope>compile</scope></dependency>
</dependencies>
知识点
Jedis 和 Lettuce
Jedis:是 Redis 官方推荐的 Java 客户端之一,出现时间较早。其提供了非常全面且直观的 API,和 Redis 命令的对应关系十分清晰,开发人员可以方便地使用这些 API 来直接操作 Redis。
Lettuce:是基于 Netty 框架实现的高性能 Redis 客户端,Netty 是一个异步事件驱动的网络应用程序框架,使得 Lettuce 具有非阻塞和异步的特性。它被广泛应用于 Spring Boot 2.x 默认的 Redis 客户端。
小技巧
区分本地运行配置和测试环境运行配置
可以在application.properties和application.yml文件中分别配置:
application.properties(本地,不提交到git)
server.port=8080
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.database=0
application.yml(提交到git)
spring:redis:host: 127.0.0.1port: 6379database: 0password:
server:port: 8080
相关文章:
【未完成】springboot项目实现扫码登录相关逻辑
准备工作 配置redis 引入redis依赖 <dependencies><!-- Spring Data Redis 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><…...
html、js、css实现爱心效果
好的!我们可以进一步美化这个爱心效果,增加更多动态和视觉吸引力。以下是改进后的代码,包括以下功能: 1. 背景渐变:添加动态背景渐变效果。 2. 爱心阴影:为爱心添加阴影,使其更具立体感。 3. 随…...
【前端】Hexo 建站指南
文章目录 前言生成站点本地测试部署云端参考 前言 更好的阅读体验:https://blog.dwj601.cn/FrontEnd/Hexo/build-your-own-website-with-hexo/ 笔记记多了,想要分享给同学们一起交流进步,该怎么办?想要搭建一个属于自己的知识库…...
OpenStack基础架构
openstack是一套IaaS云的解决方案,是一个开源的云计算管理平台 每一台物理机上都会有一个nova服务器 虚拟化其实是在nova主机里启用的 COW技术: 这么来看,3个物理机上产生10个虚拟机,所以把服务分散到10个虚拟机上和分散到4个虚拟…...
1905电影网中国地区电影数据分析(一) - 数据采集、清洗与存储
文章目录 前言一、数据采集步骤及python库使用版本1. python库使用版本2. 数据采集步骤 二、数据采集网页分析1. 分析采集的字段和URL1.1 分析要爬取的数据字段1.2 分析每部电影的URL1.2 分析每页的URL 2. 字段元素标签定位 三、数据采集代码实现1. 爬取1905电影网分类信息2. 爬…...
IPhone16 Plus 设备详情
目录 产品宣传图内部图——前内部图——后设备详细信息 产品宣传图 内部图——前 内部图——后 设备详细信息 信息收集于HubWeb.cn...
埃氏算法C++实现: 快速输出质数( 素数 )
目录 1.简介 算法原理 算法特点 应用场景 2.一般求素数方法 3.埃氏算法求素数 3.1.无动态分配 3.2.有动态分配 1.简介 埃氏算法(Eratosthenes Sieve),全称为埃拉托斯特尼筛法,是一种由古希腊数学家埃拉托斯特尼在公元…...
后端的config包中的常用配置
文章目录 一. CorsConfig二. Knife4jConfig三. MyBatisPlusConfig四. RedisTemplateConfig五. RedissonConfig 一. CorsConfig 全局跨域配置 Configuration public class CorsConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registr…...
基于亿坊PHP框架构建物联网解决方案的优势分析!
在物联网 (IoT) 领域,选到合适的框架对于整个项目的开展也尤为重要。通常情况下,基于PHP的一些主流框架被用户常选择,今天就带大家了解下基于亿坊PHP框架构建物联网解决方案的优势有哪些? 1、开发效率高 在物联网项目中…...
IoTDB结合Mybatis使用示例(增删查改自定义sql等)
IoTDB时序库是当前越来越流行以及基于其优势各大厂商越来越易接受的国产开源时序数据库,针对IoTDB的内容不做过多介绍,在使用该时序库时,往往有一定入门门槛,不同于关系型数据库或文档型数据库那般方便维护和接入开发,…...
skynet 源码阅读 -- 启动主流程
Skynet 启动主流程分析 Skynet 是一个轻量级、高并发的服务器框架。它在启动时会进行一系列初始化操作,并启动多个不同功能的线程(Monitor、Timer、Worker、Socket),从而实现消息分发、定时器、网络I/O等核心功能。本文主要从 ma…...
OpenCV:高通滤波之索贝尔、沙尔和拉普拉斯
目录 简述 什么是高通滤波? 高通滤波的概念 应用场景 索贝尔算子 算子公式 实现代码 特点 沙尔算子 算子公式 实现代码 特点 拉普拉斯算子 算子公式 实现代码 特点 高通滤波器的对比与应用场景 相关阅读 OpenCV:图像滤波、卷积与卷积核…...
UDP 广播组播点播的区别及联系
1、网络IP地址的分类 组播地址是分类编址的IPv4地址中的D类地址,又叫多播地址,他的前四位必须是1110,所以网络地址的二进制取值范围是11100000~11101111对应的十进制为 224~~239。所以以224~239开头的网络地址都是组播地址。 组播地址的功能…...
STM32补充——IAP
0 前置知识: FLASH相关内容:前往STM32补充——FLASH STM32三种烧录方式(看看就行): 1.ISP:In System Programming(在系统编程) 执行芯片厂商的 Bootloader 程序进入 ISP 模式&…...
Jetson Xavier NX (ARM) 使用 PyTorch 安装 Open3D-ML 指南
由于 Jetson 为 ARM64 (aarch64) 的系统架构,所以不能用 pip install 直接安装,需要通过源码编译。 升级系统 JetPack 由于 Open3D-ML 目前只支持 CUDA 10.0 以及 CUDA 11.*,并且 JetPack 的 CUDA 开发环境只有10.2、11.4以及12.2࿰…...
【C++高并发服务器WebServer】-1:Linux中父子进程fork创建及关系、GDB多进程调试
本文目录 一、进程创建二、GDB多进程调试 一、进程创建 在Linux中输入man 2 fork可以查看man文档中的fork的相关函数信息。 fork的作用就是创建一个子进程。 通过fork我们可以知道,创建子进程的时候,复制父进程的信息。 我们看看翻译的man文档信息&am…...
C语言数组详解:从基础到进阶的全面解析
在C语言中,数组是一种基本的数据结构,用于存储多个相同类型的数据。数组的引入使得C语言能够高效地存储和操作大量数据。在任何一个C语言程序中,数组都发挥着极其重要的作用。无论是在算法实现、数据存储、还是在复杂程序的设计中,…...
docker的前世今生
docker来自哪里? 从我们运维部署的历史来看,宿主机从最初的物理机到虚拟机,再到docker,一步步演进到现在。技术演进其实是为了解决当前技术的痛点,那我们来看看有哪些痛点以及如何克服痛点的。 物理机 一般来说&…...
python实现施瓦茨-克里斯托费尔【全网首个】根据用户输入推测函数
上代码: from sympy import symbols, integrate, simplify from sympy.plotting import plotn int(input("n:")) if n < 2:print("Error: Must n > 2") i 0 a [] aef [] A [] x, y symbols(x y) z, w symbols(z w)while i < n…...
c语言中的数组(上)
数组的概念 数组是⼀组相同类型元素的集合; 数组中存放的是1个或者多个数据,但是数组元素个数不能为0。 数组中存放的多个数据,类型是相同的。 数组分为⼀维数组和多维数组,多维数组⼀般⽐较多⻅的是⼆维数组。 数组创建 在C语言…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
