Redis实战案例1-短信登录

news2024/11/26 9:16:50

Redis的共享session应用

1. 项目的相关工作

导入sql文件

在这里插入图片描述

找到对应的sql文件即可

在这里插入图片描述

基本表的信息

在这里插入图片描述

基本架构

在这里插入图片描述

导入对应的项目文件,启动相关的service服务;
在nginx-1.18.0目录下启动命令行start nginx.exe;

2. 基于session实现登录的流程

这里利用到Javaweb中cookie和session的内容;

Javaweb中的对登录状态的校验:

Tomcat会自动把id当做cookie,发送个客户端浏览器;
从而浏览器解析并存入内存中;
然后该会话下一次请求时,会携带该cookie信息再次访问,并设置请求头id=**;
服务端就会内存中找是否有id相同的session完成校验登录状态的功能;

Redis采用缓存,判断用户存在之后将用户信息缓存到ThreadLocal

在这里插入图片描述

3. 实现发送短信验证码功能

写UserService的实现类,实现发送验证码的功能;
其中校验格式和生成验证码分别采用RegexUtils和RandomUtil工具类;

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Override
    public Result sendCode(String phone, HttpSession session) {
        // 1. 校验手机号
        if (RegexUtils.isPhoneInvalid(phone)) {
            // 2. 如果不符合,返回错误信息(采用RegexUtils的isPhoneInvalid()方法,正则表达式判断手机格式是否正确)
            return Result.fail("手机号格式错误");
        }
        // 3. 符合,生成验证码(hutool工具类中到的随机生成方法)
        String code = RandomUtil.randomNumbers(6);
        // 4. 保存验证码
        session.setAttribute("code", code);
        // 5. 发送验证码(模拟发送)
        log.debug("发送短信验证码成功,验证码:{}", code);
        // 返回ok
        return Result.ok();
    }
}

4. 实现短信验证码登录和注册功能

在这里插入图片描述

@Override
public Result login(LoginFormDTO loginForm, HttpSession session) {
    // 1. 校验手机号(从表单中获取phone)
    String phone = loginForm.getPhone();
    if (RegexUtils.isPhoneInvalid(phone)) {
        // 如果不符合,返回错误信息(采用RegexUtils的isPhoneInvalid()方法,正则表达式判断手机格式是否正确)
        return Result.fail("手机号格式错误");
    }
    // 2. 校验验证码
    // 从之前存的session中取出验证码,然后和表单中的验证码进行比较
    Object cacheCode = session.getAttribute("code");
    String code = loginForm.getCode();
    if(cacheCode == null || !cacheCode.toString().equals(code)){
        // 3. 不一致,报错(编码风格采用反向校验,避免出现菱形代码)
        return Result.fail("验证码错误");
    }
    // 4. 一致,根据手机号查询用户(extends ServiceImpl<UserMapper, User>,继承了MP,可以直接实现单表查询)
    User user = query().eq("phone", phone).one();
    // 5. 判断是否用户存在
    if(user == null) {
        // 6. 不存在,创建一个新用户并保存
        user = creatUserWithPhone(phone);
    }
    // 7. 存在,保存用户信息到session中
    session.setAttribute("user", user);
    
    return Result.ok();
}

private User creatUserWithPhone(String phone) {
    // 1. 创建用户
    User user = new User();
    user.setPhone(phone);
    user.setNickName(SystemConstants.USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));
    // 2. 保存用户(MP保存用户)
    save(user);
    return user;
}

5. 实现登录校验功能

在每个模块中都有登录校验的过程,为了实现代码简洁高效,采用拦截器的思想;
每个控制层业务中都可能需要用到拦截的用户信息,并且要保证线程安全,所以把拦截的用户信息的请求(进入Tomcat的请求都是独立的线程)存入ThreadLocal中,开辟内存空间保存线程,线程之间互不干扰;

并且,为了避免敏感信息回传给前端,只需要给出部分信息即可;

@Data
public class UserDTO {
    private Long id;
    private String nickName;
    private String icon;
}

之前在登录login中存储在session中的user修改,使用了BeanUtil工具类;

// 7. 存在,保存用户信息到session中, 使用BeanUtil工具类,自动将user中的属性复制到UserDTO中,UserDTO对象
session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));

配置拦截器配置类,添加拦截器并且设置放行资源;

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginIntercepter())
                .excludePathPatterns(
                        "/user/code",
                        "/user/login",
                        "/blog/hot",
                        "/shop/**",
                        "/shop-type/**",
                        "/upload/**",
                        "/voucher/**"
                );
    }
}

创建LoginInterceptor登录状态拦截器类;

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 获取session
        HttpSession session = request.getSession();
        // 2. 获取session中的用户
        Object user = session.getAttribute("user");
        // 3. 判断用户是否存在
        if(user == null) {
            // 4. 不存在,拦截
            return false;
        }
        // 5. 存在,保存用户信息到ThreadLocal
        UserHolder.saveUser((UserDTO) user);
        // 6. 放行
        return true;
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

最后获取对应的用户并返回user(UserDTO)信息

@GetMapping("/me")
public Result me(){
    // 获取当前登录的用户并返回
    UserDTO user = UserHolder.getUser();
    return Result.ok(user);
}

6. 集群的session共享问题

Redis替代session共享存储的主要优点:

  1. 高效性能:Redis是内存缓存数据库,具有高速访问和处理能力,可以更快地读取和写入共享的会话数据。

  2. 可扩展性:Redis能够负载均衡处理大量的并发请求,适用于分布式系统的扩展需求。

  3. 可靠性:Redis的数据存储方式比传统的文件存储更加可靠,具有数据自动备份、容错等机制,更加适用于生产环境下的应用。

因此,在分布式系统中,使用Redis作为共享存储可以提高系统的性能、可扩展性和可靠性,是一种很好的选择。

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

脚踩Midjourney、Stable Diffusion,谷歌StyleDrop真要杀疯了!

脚踩Midjourney、Stable Diffusion&#xff0c;谷歌StyleDrop真要杀疯了 导语StyleDrop组件MuseMuse架构Muse图像生成实现流程 适配器微调Adapter TuningMuse中的Adapter Tuning 反馈迭代训练 最近&#xff0c;谷歌发布了一款引人瞩目的AI绘画工具——StyleDrop。这个工具通过学…

ZYNQ - 以太网远程更新贴片SD卡应用程序【SD NAND应用】

写在前面 对于ZYNQ系列的板卡固化&#xff0c;可以通过JTAG接口&#xff0c;使用SDK固化到FLASH中&#xff0c;或者可将SD卡取出将SD卡中保存的固化工程进行修改&#xff0c;但在很多情况下&#xff0c;离线更新会很不方便&#xff0c;本文借鉴网上常见的远程更新QSPI FLASH的…

解析Java异常机制:捕获编程中的错误,保障代码稳定性

工作中&#xff0c;程序遇到的情况不可能完美。比如&#xff1a;程序要打开某个文件&#xff0c;这个文件可能不存在或者文件格式不对&#xff1b;程序在运行着&#xff0c;但是内存或硬盘可能满了等等。 软件程序在运行过程中&#xff0c;非常可能遇到刚刚提到的这些问题&…

java OpenCSV自定义列标题和列位置

背景:最近使用csv进行数据导出&#xff0c;提高导出性能 问题&#xff1a;CsvBindByName和CsvBindByPosition不能同时用&#xff0c;要么是没标题要么是不是指定的排序规则 实现思路&#xff1a; 自定义排序规则&#xff0c;HeaderNameBaseMappingStrategy的writeOrder 属性可…

C++基于jrtp实现rtp发送与接收代码实现(附源码)

C++常用功能源码系列 文章目录 C++常用功能源码系列前言一、jrtp是什么二、rtp sender源码三、rtp receive源码总结前言 本文是C/C++常用功能代码封装专栏的导航贴。部分来源于实战项目中的部分功能提炼,希望能够达到你在自己的项目中拿来就用的效果,这样更好的服务于工作实…

Mininet拓扑构建与命令使用

实验目的&#xff1a; 1、通过命令模拟创建SDN网络。 2、深入了解Mininet的命令使用。 3、学会使用网络构建启动参数、内部交互命令及外部运行参数。 实验环境&#xff1a; 设备名称软件环境硬件环境主机Mininet_2.2.0_desktop_cv1.1CPU&#xff1a;1核 内存&#xff1a;2G 磁…

【MySQL数据库】MySQL数据库管理

MySQL数据库管理 一、数据库简述1.1简介1.2数据库基本概念1.3数据库的发展史1.3主流的数据库介绍1.4数据库的类型1.4.1关系型数据库特点1.4.2非关系型数据库介绍 1.5SQL语言分类 二、数据库基础应用2.1查看数据库2.2创建新的库、表2.3删除库、表2.4管理表中的数据记录2.4.1插入…

Java新技术和趋势:如何应对Java生态的变化和发展趋势

章节一&#xff1a;引言 Java是一门广泛使用的编程语言&#xff0c;具有强大的生态系统和持续的发展。随着时间的推移&#xff0c;Java生态系统不断演进和改变&#xff0c;出现了许多新技术和趋势。在本文中&#xff0c;我们将探讨一些最新的Java技术和趋势&#xff0c;并分享…

路径规划算法:基于适应度相关优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于适应度相关优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于适应度相关优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能…

路径规划算法:基于社会群体优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于社会群体优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于社会群体优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化…

【Linux】Nginx+Tomcat负载均衡、动静分离、多实例部署

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 NginxTomcat负载均衡、动静分离、多实例部署 一、Tomcat 多实例部署1.安装好 jdk 及 tomcat2.配置 tomcat 环境变量3.修改 tomcat2 中的 server.xml 文件4.修改各 tomcat 文件…

RocketMQ源码解析之消息存储机制

RocketMQ是一款开源的分布式消息中间件,在大数据、云计算等领域具有广泛的应用。要想深入了解RocketMQ的源码实现,首先需要了解它的消息存储机制。 RocketMQ采用的是文件存储的方式,即RocketMQ将消息以文件的形式存储在磁盘上。具体来说,RocketMQ将消息存储在commitlog文件…

精通postman教程(三)postman各模块详解

作为一名测试工程师&#xff0c;那么Postman绝对是大伙必备的工具之一。 在这个系列教程中&#xff0c;我将为大伙详细讲解如何使用Postman进行API测试。 今天我为大伙介绍Postman的各个模块&#xff0c;让你们快速上手这款工具。 一、顶部及左侧工作栏 1、My Workspace - …

java基础(多线程)-常用方法具体使用

一、Thread.start()方法 start()方法&#xff1a;启动子线程 new Thread();当前线程的状态为NEW 调用start()方法之后当前线程的状态变为RUNNABLE 二、Thread.sleep()静态方法 1. 调用sleep会让当前线程从Running进入Timed Waiting 状态 2.其他线程可以使用interrupt方法…

ES6相关概念

什么是ES6&#xff1f; ES 的全称是 ECMAScript , 它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范。 为什么使用 ES6 ? 每一次标准的诞生都意味着语言的完善&#xff0c;功能的加强。JavaScript语言本身也有一些令人不满意的地方。 变量提升特性增加了程序运行…

一文讲清超算,高性能计算,并行计算,分布式计算的区别

摘要: 超算、高性能计算、并行计算和分布式计算是计算领域中的重要概念&#xff0c;但它们之间的区别常常令人困惑。本文将为你解析它们的概念与特点&#xff0c;让你在这个领域里轻松游刃有余。 ... ... 超算、高性能计算、并行计算和分布式计算是计算领域中的重要概念&#x…

LVS + Keepalived群集

文章目录 LVS Keepalived1 Keepalived及其工作原理2 一个健康的集群的特点3 Keepalived常见问题脑裂3.1 原因3.2 预防3.3 配置 4 部署keepalived4.1 部署192.168.146.204.2 部署192.168.146.30 5 LVSKeepalived高可用群集5.1 部署192.168.146.50(nginx)5.2 部署192.168.146.60…

在家就能赚钱的方法,我不允许你还不知道

近年来&#xff0c;随着互联网的迅猛发展&#xff0c;具有敏锐嗅觉的人们只需利用互联网&#xff0c;就能愉快地获取收入。一般而言&#xff0c;在线赚钱所需的投资较少&#xff0c;有时只需一台可上网的电脑或手机即可满足&#xff0c;因此有时被称为“零成本或低成本网络赚钱…

Vue学习 之 第一个Vue应用

第一个 Vue 应用 安装WebStorm 在这之前&#xff0c;已下载安装好了WebStorm。 打开WebStorm&#xff0c;点击”“就可以创建一个新的应用。 项目文件目录地址&#xff1a; /Users/morris/WebstormProjects 或者在 file -> new priject 也可以新建一个项目 新建一个 ht…

中小商户如何实现门店数字化运营与管理,有没有好用的工具推荐?

中小商户开展门店数字化运营与管理&#xff0c;能够实现在线支付、退货、换货等快速操作&#xff0c;针对性的精准营销和服务&#xff0c;增加客户忠诚度。 门店数字化运营与管理可以帮助商家建立全面、实时的业务数据管理系统&#xff0c;提高工作效率和客户满意度&#xff0c…