用户相关操作
约 955 字大约 3 分钟
2025-03-13
1. 整体架构
此项目运用了 Spring Boot 框架构建 Web 应用,采用 MVC(Model - View - Controller)架构模式。Controller 层负责处理 HTTP 请求,Service 层承担业务逻辑处理,Mapper 层(借助 MyBatis - Plus 实现)负责与数据库交互。
2. 注册功能实现技术
2.1 接口定义
在 UserController
里定义了 /user/register
接口,其接收 UserRegisterRequest
对象,这是一个封装了用户注册所需信息(如用户账户、密码、确认密码)的 DTO(Data Transfer Object)。
@PostMapping("/register")
public BaseResponse<Long> userRegister(@RequestBody UserRegisterRequest userRegisterRequest) {
// ...
}
2.2 业务逻辑处理
UserServiceImpl
类中的 userRegister
方法实现了注册的具体逻辑:
- 参数校验:检查用户账户、密码和确认密码是否为空,以及账户长度是否小于 4 位、密码长度是否小于 8 位,还有两次输入的密码是否一致。
if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
}
if (userAccount.length() < 4) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短");
}
if (userPassword.length() < 8 || checkPassword.length() < 8) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短");
}
if (!userPassword.equals(checkPassword)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
}
- 账户唯一性检查:使用
QueryWrapper
查询数据库,判断该账户是否已存在。
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userAccount", userAccount);
long count = this.baseMapper.selectCount(queryWrapper);
if (count > 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
}
- 密码加密:运用
DigestUtils.md5DigestAsHex
方法对密码进行 MD5 加密,同时添加盐值(SALT
)增强安全性。
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
- 数据插入:创建
User
对象,将加密后的密码和用户账户信息存入其中,再调用save
方法将用户信息插入数据库。
User user = new User();
user.setUserAccount(userAccount);
user.setUserPassword(encryptPassword);
boolean saveResult = this.save(user);
if (!saveResult) {
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败,数据库错误");
}
3. 登录功能实现技术
3.1 接口定义
在 UserController
中定义了 /user/login
接口,接收 UserLoginRequest
对象和 HttpServletRequest
对象。
@PostMapping("/login")
public BaseResponse<LoginUserVO> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
// ...
}
3.2 业务逻辑处理
UserServiceImpl
类中的 userLogin
方法实现了登录的具体逻辑:
- 参数校验:检查用户账户和密码是否为空,以及账户长度是否小于 4 位、密码长度是否小于 8 位。
if (StringUtils.isAnyBlank(userAccount, userPassword)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
}
if (userAccount.length() < 4) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号错误");
}
if (userPassword.length() < 8) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");
}
- 密码加密:同样使用
DigestUtils.md5DigestAsHex
方法对输入的密码进行 MD5 加密,并添加盐值。
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
- 用户查询:使用
QueryWrapper
根据用户账户和加密后的密码查询数据库,判断用户是否存在。
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userAccount", userAccount);
queryWrapper.eq("userPassword", encryptPassword);
User user = this.baseMapper.selectOne(queryWrapper);
if (user == null) {
log.info("user login failed, userAccount cannot match userPassword");
throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误");
}
- 记录登录状态:将用户信息存入
HttpSession
中,以此记录用户的登录状态。
request.getSession().setAttribute(USER_LOGIN_STATE, user);
4. 注销功能实现技术
4.1 接口定义
在 UserController
中定义了 /user/logout
接口,接收 HttpServletRequest
对象。
@PostMapping("/logout")
public BaseResponse<Boolean> userLogout(HttpServletRequest request) {
// ...
}
4.2 业务逻辑处理
UserServiceImpl
类中的 userLogout
方法实现了注销的具体逻辑:
- 检查登录状态:判断
HttpSession
中是否存在用户登录状态信息。
if (request.getSession().getAttribute(USER_LOGIN_STATE) == null) {
throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录");
}
- 移除登录状态:从
HttpSession
中移除用户登录状态信息。
request.getSession().removeAttribute(USER_LOGIN_STATE);
5. 其他技术要点
- 异常处理:运用自定义的
BusinessException
类处理业务异常,通过ErrorCode
枚举类统一管理错误码。 - 数据脱敏:定义
LoginUserVO
和UserVO
类对用户信息进行脱敏处理,避免敏感信息泄露。 - 线程安全:在用户注册和微信登录时,使用
synchronized
关键字保证同一账户或unionId
的操作是线程安全的。