黑马点评学习笔记03(Hutool工具库)
前言
首先登陆界面首先还是基于session实现(我当时也很惊讶,怎么用这个😯,结果看了目录,后面就用Redis和Jwt令牌)可能就是一个过渡吧,先用Session实现一遍,然后才能突出后面的很厉害。其实里面还是有很多小知识点的(Hutool)很值得学习,这个Session实现就当小配角,陪跑🤪我们学。
先来看看登陆界面的代码实现:
UserController类 :
先来看看登陆界面的代码实现:
UserController类 :
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Resourceprivate IUserService userService;/*** 发送手机验证码*/@PostMapping("code")public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {// TODO 发送短信验证码并保存验证码return userService.sendCode(phone, session);}/*** 登录功能* @param loginForm 登录参数,包含手机号、验证码;或者手机号、密码*/@PostMapping("/login")public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){// TODO 实现登录功能return userService.login(loginForm, session);}
IUserService 接口:
package com.hmdp.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.hmdp.dto.LoginFormDTO;
import com.hmdp.dto.Result;
import com.hmdp.entity.User;import javax.servlet.http.HttpSession;/*** <p>* 服务类* </p>** @author 虎哥* @since 2021-12-22*/
public interface IUserService extends IService<User> {Result sendCode(String phone, HttpSession session);Result login(LoginFormDTO loginForm, HttpSession session);}
IUserService 接口实现类:
package com.hmdp.service.impl;import.../*** <p>* 服务实现类* </p>** @author 虎哥* @since 2021-12-22*/
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result sendCode(String phone, HttpSession session) {//1.校验手机号if (RegexUtils.isPhoneInvalid(phone)) {// 2.如果不符合,返回错误信息return Result.fail("手机号格式错误!");}//3.符合,生成验证码String code = RandomUtil.randomNumbers(6);//4.保存验证码到sessionsession.setAttribute("code", code);//5.发送验证码System.out.println("发送短信验证码成功,验证码:" + code);//5.返回okreturn Result.ok();}@Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {//1.校验手机号String phone = loginForm.getPhone();if (RegexUtils.isPhoneInvalid(phone)) {// 2.如果不符合,返回错误信息return Result.fail("手机号格式错误!");}//2.校验验证码 不一致直接报错 从session中获取Object cachecode = session.getAttribute("code");String code = loginForm.getCode();if (cachecode == null || !cachecode.toString().equals(code)) {return Result.fail("验证码错误!");}//3.一致,根据手机号查询用户 select * from tb_user where phone = ?User user = query().eq("phone", phone).one();//4.判断用户是否存在if (user == null) {//5.不存在,创建新用户user = createUserWithPhone(phone);}//6.存在,保存用户信息到sessionsession.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));return Result.ok();}private User createUserWithPhone(String phone) {//1.创建用户User user = new User();user.setPhone(phone);user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));//2.保存用户save(user);return user;}}
就是很常见的基于session存储来实现的登陆界面,以及Interceptor拦截器,很简单,之前写苍穹外卖的时候都写过了,所以只总结一些新的东西。
🌟 Hutool 简介
Hutool 是一个功能丰富、开箱即用的 Java 工具类库,它封装了常用的 JDK 操作,简化开发流程,提高编码效率。其核心模块包括:
- hutool-core:核心工具类(本代码用到的都在此模块)
- hutool-crypto:加密解密
- hutool-http:HTTP 客户端
- hutool-json:JSON 处理
- hutool-cache:缓存
…
官网: https://hutool.cn
依赖:
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.17</version>
</dependency>
跟大家说一个学习的小技巧:学习一个项目可以先看看它的依赖,Java毕竟是一个具有封装,继承特性的语言,看看它引入了什么依赖就大概了解到其所使用的技术。
来看看上面代码都使用了 哪些Hutool 工具类库中的功能?
✅ 一、RandomUtil.randomNumbers(6) —— 随机数字生成
🔹 所属类:cn.hutool.core.util.RandomUtil
🔹 方法签名:
public static String randomNumbers(int count)
源代码:
String code = RandomUtil.randomNumbers(6);
- 底层实现原理:
- 使用 ThreadLocalRandom(线程安全的随机数生成器)。
- 遍历 count 次,每次生成 0-9 的随机整数,拼接成字符串。
- 不依赖 Math.random(),性能更好。
✅ 二、BeanUtil.copyProperties(user, UserDTO.class) —— Bean 属性拷贝
🔹 所属类:cn.hutool.core.bean.BeanUtil
🔹 方法签名:
public static <T> T copyProperties(Object source, Class<T> targetClass)
🔹 功能说明:
将源对象(如 User 实体类)的属性值拷贝到目标类(如 UserDTO)的新实例中,基于 属性名匹配 + 类型自动转换。
源代码:
session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));
将数据库查询出的 User 实体对象转换为 UserDTO(数据传输对象),避免将敏感字段暴露给前端或 session。
package com.hmdp.entity;import ...
/*** <p>* * </p>** @author 虎哥* @since 2021-12-22*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tb_user")
public class User implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 手机号码*/private String phone;/*** 密码,加密存储*/private String password;/*** 昵称,默认是随机字符*/private String nickName;/*** 用户头像*/private String icon = "";/*** 创建时间*/private LocalDateTime createTime;/*** 更新时间*/private LocalDateTime updateTime;}@Data
public class UserDTO {private Long id;private String nickName;private String icon;
//少了好多敏感字段,只保存拦截器想要的
}
🔹 底层机制:
- 使用反射获取源对象和目标类的所有 getter 和 setter 方法。
- 匹配同名属性(忽略大小写可配置)。
- 自动进行类型转换(如 Long → String,String → Integer 等)。
- 调用目标对象的 setter 设置值。
最后再扩展一下吧,以后的代码中也要用
1. StrUtil:字符串处理
StrUtil.isBlank(str) // 判断空字符串
StrUtil.trim(str) // 去空格
StrUtil.sub(str, 0, 10) // 截取字符串
2. ObjectUtil:对象判空
ObjectUtil.isNull(obj)
ObjectUtil.isNotEmpty(collection)
3. Convert:类型转换
int i = Convert.toInt("123", 0);
long l = Convert.toLong(obj, 0L);
本文是学习黑马程序员—黑马点评项目的课程笔记,小白啊!!!写的不好轻喷啊🤯如果觉得写的不好,点个赞吧🤪(批评是我写作的动力)
…。。。。。。。。。。。…
…。。。。。。。。。。。…
