【未完成】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语言…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
