1.Controller层代码
首先就是简单的收到前端传输的数据,这里将其封装成了UserLoginRequest类,然后首先判断请求是否为空,空则抛出异常(自定义了一个异常类)。判断请求不为空后,则开始判断传输过来的账号和密码是否为空,空则抛出异常, 若不为空,则进入service层进入下一步操作,若登录成功,会返回一个脱敏的用户类LoginUserVo,然后再将其包装在返回工具类ResultUtils类中返回给前端。
@PostMapping("/login")
public BaseResponse<LoginUserVO> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
if (userLoginRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
String userAccount = userLoginRequest.getUserAccount();
String userPassword = userLoginRequest.getUserPassword();
if (StringUtils.isAnyBlank(userAccount, userPassword)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
LoginUserVO loginUserVO = userService.userLogin(userAccount, userPassword, request);
return ResultUtils.success(loginUserVO);
}
用户登录只需传输用户账号和密码,将其封装成一个请求类。
public class UserLoginRequest implements Serializable {
private static final long serialVersionUID = 3191241716373120793L;
private String userAccount;
private String userPassword;
}
BaseResponse类是一个包装好的回复类,用于给前端返回完整的业务信息,其中包括三个属性:code(状态码),data(需要返回的数据),message(返回信息)
@Data
public class BaseResponse<T> implements Serializable {
private int code;
private T data;
private String message;
public BaseResponse(int code, T data, String message) {
this.code = code;
this.data = data;
this.message = message;
}
public BaseResponse(int code, T data) {
this(code, data, "");
}
public BaseResponse(ErrorCode errorCode) {
this(errorCode.getCode(), null, errorCode.getMessage());
}
}
UserLoginVo类是为了给用户脱敏,因为不能返回给用户返回一些比较关键的属性,如用户id,因此需要对User类进行一些删减,生成一个新的不带重要信息的类返回给前端。如下:
@Data
public class LoginUserVO implements Serializable {
/**
* 用户 id
*/
private Long id;
/**
* 用户昵称
*/
private String userName;
/**
* 用户头像
*/
private String userAvatar;
/**
* 用户简介
*/
private String userProfile;
/**
* 用户角色:user/admin/ban
*/
private String userRole;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
private static final long serialVersionUID = 1L;
}
ResultUtils类,专门用于返回结果给前端的类,其内实际上封装了一个BaseResponse类,具体代码如下:
public class ResultUtils {
/**
* 成功
*
* @param data
* @param <T>
* @return
*/
public static <T> BaseResponse<T> success(T data) {
return new BaseResponse<>(0, data, "ok");
}
/**
* 失败
*
* @param errorCode
* @return
*/
public static BaseResponse error(ErrorCode errorCode) {
return new BaseResponse<>(errorCode);
}
/**
* 失败
*
* @param code
* @param message
* @return
*/
public static BaseResponse error(int code, String message) {
return new BaseResponse(code, null, message);
}
/**
* 失败
*
* @param errorCode
* @return
*/
public static BaseResponse error(ErrorCode errorCode, String message) {
return new BaseResponse(errorCode.getCode(), null, message);
}
}
2.Service层
在Controller层简单的校验过用户账号和密码均不为空后,需要进入Service层进行下一步判断。在这里做了几个比较基础的校验(由于是自己写的一个小系统),仅判断了账户长度以及密码的长度,并且在注册时给用户的密码进行了一个md5加密。在经过校验后,使用QueryWrapper类对其进行了一个检索,这里集成了MybatisPlus,直接使用BaseMapper中的selectOne单个查询查找出对应的用户。若用户不存在,抛出异常;用户存在则说明登录成功,将其状态保存在request域中,最后将得到的user进行一个脱敏然后返回给Controller层。
public LoginUserVO userLogin(String userAccount, String userPassword, HttpServletRequest request) {
// 1. 校验
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, "密码错误");
}
// 2. 加密
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
// 查询用户是否存在
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, "用户不存在或密码错误");
}
// 3. 记录用户的登录态
request.getSession().setAttribute(USER_LOGIN_STATE, user);
return this.getLoginUserVO(user);
}
返回脱敏用户操作,使用BeanUtils.copyProperties方法将user中可以返回的数据拷贝到loginUserVO中,然后返回回去。
@Override
public LoginUserVO getLoginUserVO(User user) {
if (user == null) {
return null;
}
LoginUserVO loginUserVO = new LoginUserVO();
BeanUtils.copyProperties(user, loginUserVO);
return loginUserVO;
}
3.Mapper层
集成了MP后,不需要自己操作了。