news 2026/5/11 12:26:02

redis_点评详解(02.短信登录-验证码登录注册)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
redis_点评详解(02.短信登录-验证码登录注册)

controller

@PostMapping("/login") public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){ //实现登录功能 return userService.login(loginForm,session); }

一、@RequestBody LoginFormDTO loginForm

@Data public class LoginFormDTO { private String phone; private String code; private String password; }
1、前端传过来的是JSON格式

前端登录时,会传递:

{ "phone": "13800138000", "code": "123456", "password": "" }

@RequestBody作用:接收JSON参数,并自动封装成 Java 对象。(没有这个注解,Spring 无法解析 JSON。)

2、DTO = Data Transfer Object(数据传输对象)

作用:

  1. 封装前端传来的所有登录参数(phone、code、password)

  2. 不用写多个参数,一个对象接收,更整洁、直接传loginForm对象即可

3、为什么加@Date
  • 所属框架:Lombok框架提供的注解

  • 自动生成方法:

getter / setter

toString

equals / hashCode

不用手写,简化代码、让 Spring 可以自动封装JSON数据

@Data在当前登录代码里的实际用处是配合 @RequestBody 自动封装 JSON,前端传 JSON 手机号、验证码,Spring 能自动把 JSON 映射到 LoginFormDTO 对象,必须要有 setter 才能注入赋值。

4、总结:前端传 JSON → @RequestBody 接收 → 自动封装进 LoginFormDTO 对象 → 方便后续业务使用。

二、HttpSession session

  • 所属包:javax.servlet.http.HttpSession(属于 Java Web Servlet 原生 内置对象)

  • 作用:服务端会话技术,用来保存当前浏览器用户的私有数据,记录登录状态、临时数据

  • 常用两个核心方法:

    • 1、存数据

      • session.setAttribute("key", 对象/数据);

      • key-value键值对把数据存在服务端当前用户会话中

    • 2、取数据

      • session.getAttribute("key");

      • 根据 key 取出之前存入的数据

ServiceImpl

@Override public Result login(LoginFormDTO loginForm, HttpSession session) { //1.校验手机号 String phone = loginForm.getPhone(); if(RegexUtils.isPhoneInvalid(phone)){ //2.如果不符合,返回错误信息 return Result.fail("手机号格式错误"); } //2.校验验证码 String code = loginForm.getCode(); Object cacheCode = session.getAttribute("code"); if(cacheCode==null||!cacheCode.toString().equals(code)) { //3.不一致,报错 return Result.fail("验证码错误"); } //4.一致,根据手机号查询用户 select * from tb_user where phone = ? //eq 是「Equal」的缩写,意思是「等于」,对应 SQL 中的 WHERE phone = ?。 //因为上述<UserMapper, User>中User方法中使用了@TableName("tb_user")指定实体类对应数据库表名的,否则需要加通过 from() 方法显式指定表名 tb_user: //User user = query().from("tb_user").eq("phone", phone).one(); User user = query().eq("phone", phone).one();//这里查一个就是.one(),查多个就是list() //5.判断用户是否存在 if(user==null){ //6.不存在创建新用户并保存 user=createUserWithPhone(phone); } //7.存在-保存用户信息到session中 session.setAttribute("user",user); return Result.ok(); } private User createUserWithPhone(String phone) { //1.创建用户 User user=new User(); user.setPhone(phone); //向user中插入一个随机的用户昵称 user.setNickName("user_"+RandomUtil.randomString(10)); /*setNickName 是 User 实体类中的Setter(设置器)方法,作用是给 User 对象的 nickName(昵称)字段赋值。 你看不到这个方法的手写代码,是因为 User 类上标注了 @Data 注解(Lombok 框架提供),Lombok 会在编译时自动生成这个方法,无需你手动编写。*/ //2.保存用户到数据库(MyBatis-Plus 提供的方法) // save(user) 等价于执行 INSERT INTO tb_user (phone, nick_name, icon, ...) VALUES (?, ?, ?, ...) save(user); return user; }

三、为什么 session.getAttribute ("code") 返回类型是 Object

Object cacheCode = session.getAttribute("code");

根据上述我们知道取出来的是之前插入的数据,那为什么返回值类型却是Object呢?

session.getAttribute("key")可以存任何类型的数据

但是HttpSession是一个通用容器、设计上不限制存储的数据类型,程序运行时无法提前预知你存入的具体是什么类型。所以统一用Object接收(所有类的父类);然后接下来向下强制类型转换(强转);

四、MyBatis-Plus 链式查询:query().eq("phone", phone).one();

等价于 SQL:SELECT * FROM tb_user WHERE phone = ?

query()MP 提供的链式查询构造器,开启查询操作。

eq("字段名", 值)eq = Equal(等于),对应 SQL 的WHERE条件。

one()表示查询 1 条结果并返回对象;若查询多条数据使用list()

1、为什么代码中不使用 from () 声明表名?

  • 1、User 实体类上使用了@TableName("tb_user")注解

@TableName("tb_user") public class User implements Serializable { }

这个注解是MyBatis-Plus提供的,作用是:

告诉 MyBatis-Plus,当前User类对应数据库里的tb_user表。

  • 2、MyBatis-Plus 会自动识别表名

因为UserServiceImpl继承了ServiceImpl<UserMapper, User>

  • 泛型中指定了操作的实体是User

  • MP 自动读取User类上的@TableName("tb_user")

  • 自动拼接成from tb_user

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 12:24:13

解锁you-get进阶玩法:Cookie配置与ffmpeg环境搭建实战

1. 为什么需要Cookie和ffmpeg&#xff1f; 很多朋友在用you-get下载视频时&#xff0c;可能会遇到两个常见问题&#xff1a;一是遇到会员专享视频无法下载&#xff0c;二是下载后的视频出现音画不同步或无法播放的情况。这两个问题其实分别对应了Cookie配置和ffmpeg环境搭建的…

作者头像 李华
网站建设 2026/5/11 12:24:12

工程实践:非专业程序员用 AI 做产品,也需要 API 化思维

这类内容的核心判断应该换一下&#xff1a;用户不是先想买 API&#xff0c;中间才想到 Claude / Codex&#xff1b;很多时候正相反&#xff0c;是先想用 Claude / Codex 提升开发效率&#xff0c;才开始寻找稳定、可接入、可支付、可迁移的 API 入口。目标用户画像产品经理、运…

作者头像 李华
网站建设 2026/5/11 12:21:58

Layerdivider终极指南:3步将单张图片智能分层为可编辑PSD

Layerdivider终极指南&#xff1a;3步将单张图片智能分层为可编辑PSD 【免费下载链接】layerdivider A tool to divide a single illustration into a layered structure. 项目地址: https://gitcode.com/gh_mirrors/la/layerdivider 你是否曾面对一张精美的插画作品&am…

作者头像 李华
网站建设 2026/5/11 12:19:38

动态量子电路基准测试框架dynamarq解析与应用

1. 动态量子电路基准测试框架dynamarq解析 量子计算正从理论走向实践&#xff0c;而动态量子电路&#xff08;Dynamic Quantum Circuits&#xff09;作为其中的关键技术&#xff0c;正在量子纠错、算法优化等领域展现出独特优势。与传统静态电路不同&#xff0c;动态电路允许在…

作者头像 李华
网站建设 2026/5/11 12:17:08

PostgreSQL 跨表数据同步实战:Update Join 与 Delete Using 核心指南

1. 为什么需要跨表数据同步&#xff1f; 在日常数据库运维中&#xff0c;经常会遇到这样的场景&#xff1a;你需要根据另一张表的数据规则&#xff0c;批量更新或清理主表的数据。比如电商系统中根据商品类别更新折扣价&#xff0c;或者根据黑名单清理用户数据。这类操作如果逐…

作者头像 李华
网站建设 2026/5/11 12:17:07

从数学抽象到物理连接:Simscape物理网络建模的核心思想

1. 当信号流遇到物理网络&#xff1a;思维模式的碰撞 第一次打开Simscape工具箱时&#xff0c;我盯着那些陌生的元件库发了十分钟呆。作为有五年Simulink建模经验的工程师&#xff0c;我习惯性地开始寻找"输入端口"和"输出端口"&#xff0c;却发现Simscape…

作者头像 李华