用户中心系统总结
用户中心系统
一.result封装类:
(1)首先要有一个基本的BaseResult封装类,里面有对应的属性(如状态码、数据、信息、描述),此类需要实现序列化。
@Data
public class BaseResult<T> implements Serializable {
private static final long serialVersionUID = 1L;
private int code;
private T data;
private String message;
private String description;
BaseResult(int code, T data, String message, String description) {
this.code = code;
this.data = data;
this.message = message;
this.description = description;
}
BaseResult( T data, String message, String description) {
this.data = data;
this.message = message;
this.description = description;
}
BaseResult(int code, T data) {
this.code = code;
this.data = data;
}
BaseResult(){
this.code = 200;
this.message = "success";
}
BaseResult( T data) {
this.code = 200;
this.data = data;
this.message = "success";
this.description = "请求成功";
}
BaseResult(int code, String message, String description) {
this.code = code;
this.message = message;
this.description = description;
}
BaseResult(int code, String message) {
this.code = code;
this.message = message;
}
BaseResult(ErrorCode errorCode, String message) {
this.code = errorCode.getCode();
this.message = message;
}
}
(2)需要有一个枚举类叫做ErrorCode,这个类的作用是将一些错误信息写死,需要的时候直接进行引用即可,如果有新的错误信息的话再增加这个类的内容即可,降低程序的耦合性。
public enum ErrorCode {
SUCCESS(200,"成功","请求成功"),
NOT_FOUND(404,"请求失败","找不到资源"),
BAD_REQUEST(400,"请求失败","客户端错误"),
UNAUTHORIZED(401,"请求失败","请求要求用户的身份认证"),
PARAMS_ERROR(40000, "请求参数错误", ""),
NULL_ERROR(40001, "请求数据为空", ""),
NOT_LOGIN(40100, "未登录", ""),
NO_AUTH(40101, "无权限", ""),
FORBIDDEN(40301, "禁止操作", ""),
SYSTEM_ERROR(50000, "系统内部异常", "");
private int code;
private String msg;
private String desc;
ErrorCode(int code, String message, String description){
this.code = code;
this.msg = message;
this.desc = description;
}
public String getMsg() {
return msg;
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
(3)编写Result类,这个类中重载了很多方法成功和错误响应的方法。
public class Result {
public static <T> BaseResult<T> success(T data){
return new BaseResult<>(data);
}
public static <T> BaseResult<T> error(ErrorCode errorCode , String message , String description){
return new BaseResult<>(errorCode.getCode(),errorCode.getMsg(),errorCode.getDesc());
}
public static <T> BaseResult<T> error(int code , String message , String description){
return new BaseResult<>(code,message,description);
}
public static <T> BaseResult<T> error(int code , String message ){
return new BaseResult<>(code,message);
}
public static <T> BaseResult<T> error( ErrorCode errorCode, String message ){
return new BaseResult<>(errorCode,message);
}
public static <T> BaseResult<T> success( ){
return new BaseResult<>();
}
}
二、捕获异常类
(1)构建BusinessException类(构造一个异常类)
这个类继承RuntimeException,具有属性code(状态码),desc(错误详细信息)两个属性,message的值在构造函数的时候引用RuntimeException的或者引用刚刚ErrorCode中的message。
public class BusinessException extends RuntimeException{
private final int code;
private final String desc;
public BusinessException(String message, int code, String desc) {
super(message);
this.code = code;
this.desc = desc;
}
public BusinessException(ErrorCode errorCode) {
super(errorCode.getMsg());
this.code = errorCode.getCode();
this.desc = errorCode.getDesc();
}
public BusinessException(ErrorCode errorCode, String description) {
super(errorCode.getMsg());
this.code = errorCode.getCode();
this.desc = description;
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
(2)设置全局捕获器GlobalExceptionHandler。
其实这个全局捕获器就是捕获刚刚定义好的异常,然后在这里返回异常的信息。其中用到两个注解。
1.@RestControllerAdvice
@RestControllerAdvice 是一个用于 统一捕获并处理 REST 控制器异常 的复合注解,它等价于 @ControllerAdvice + @ResponseBody,能确保异常信息以 JSON 格式 返回给客户端。
核心作用
全局拦截异常:捕获所有 @RestController 抛出的异常。统一响应格式:避免返回 HTML 视图,直接输出 JSON 数据。解耦业务与异常处理:控制器专注业务逻辑,异常集中管理。
2.ExceptionHandler
在Spring框架中,@ExceptionHandler注解是用于处理控制器(Controller)中抛出的异常。通过定义一个或多个异常处理方法,并使用@ExceptionHandler进行标注,可以实现对特定异常的捕获和处理。这种方式不仅可以减少代码中的异常处理逻辑,还可以提供更加统一和清晰的异常处理策略。
三、mybatis-plus注意点
1.可用mybatis-X来生成对应的实体、servie、mapper的代码
2.mybatis-plus 和 mybatis 依赖只能有一个。
3.同时要把xml文件中的映射关系配置正确
四、定义常量接口constant
public interface UserConstant {
/**
* 用户登录态键
*/
String USER_LOGIN_STATE = "userLoginState";
// ------- 权限 --------
/**
* 默认权限
*/
int DEFAULT_ROLE = 0;
/**
* 管理员权限
*/
int ADMIN_ROLE = 1;
}
五、实体对象类
对象有user实体对象,具有user的全部属性,在进行注册和登陆的时候,又需要两个类UserRegisterRequest和UserLoginRequest两个类去接受登录和注册的信息,这些类都需要实现序列化。
user:
@Data
@TableName(value = "user")
public class User implements Serializable {
@TableId(type = IdType.AUTO)
private long id;
private String username;
private String userAccount;
private String avatarUrl;
private int gender;
private String userPassword;
private String phone;
private String email;
private int userStatus;
private Date createTime;
private Date updateTime;
@TableLogic
private int isDelete;
private int userRole;
private String planetCode;
private String tags;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
UserRegisterRequest:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserRegisterRequest implements Serializable {
private static final long serialVersionUID = 3191241716373120793L;
private String userAccount;
private String userPassword;
private String checkPassword;
private String planetCode;
public String getUserAccount() {
return userAccount;
}
public void setUserAccount(String userAccount) {
this.userAccount = userAccount;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public String getCheckPassword() {
return checkPassword;
}
public void setCheckPassword(String checkPassword) {
this.checkPassword = checkPassword;
}
public String getPlanetCode() {
return planetCode;
}
public void setPlanetCode(String planetCode) {
this.planetCode = planetCode;
}
}
UserLoginRequest:
@Data
public class UserLoginRequest implements Serializable {
private static final long serialVersionUID = 3191241716373120793L;
private String userAccount;
private String userPassword;
public String getUserAccount() {
return userAccount;
}
public void setUserAccount(String userAccount) {
this.userAccount = userAccount;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
}
六、功能实现
用户注册:
@PostMapping("/register")
public BaseResult<Long> userRegister(@RequestBody UserRegisterRequest userRegisterRequest) {
if (userRegisterRequest == null){
throw new BusinessException(ErrorCode.UNAUTHORIZED);
}
String userAccount = userRegisterRequest.getUserAccount();
String userPassword = userRegisterRequest.getUserPassword();
String checkPassword = userRegisterRequest.getCheckPassword();
String planetCode = userRegisterRequest.getPlanetCode();
if (StringUtils.isAnyBlank(userAccount,userPassword,checkPassword,planetCode)){
throw new BusinessException(ErrorCode.UNAUTHORIZED);
};
Long result = userservice.userRegister(userAccount,userPassword,checkPassword,planetCode);
return Result.success(result);
}
密码要用盐值加密:
//1.校验
if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword, planetCode)) {
throw new BusinessException(ErrorCode.UNAUTHORIZED,"参数为空");
}
if (userAccount.length()<4){
throw new BusinessException(ErrorCode.UNAUTHORIZED,"用户账号错误");
}
if (userPassword.length()<8 || checkPassword.length()<8){
throw new BusinessException(ErrorCode.UNAUTHORIZED,"用户密码过");
}
if (planetCode.length() > 5) {
throw new BusinessException(ErrorCode.UNAUTHORIZED, "星球编号过长");
}
// 2.账户不能包含特殊字符
String validPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
if (matcher.find()) {
throw new BusinessException(ErrorCode.UNAUTHORIZED,"用户账户具有特殊字符");
}
//3.密码不能为空
if (userPassword == null ){
throw new BusinessException(ErrorCode.UNAUTHORIZED,"密码不能为空");
}
//4.密码要和校验密码相同
if (!userPassword.equals(checkPassword)){
throw new BusinessException(ErrorCode.UNAUTHORIZED,"两次密码输入不一致");
}
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userAccount", userAccount);
long count_userAccount = userMapper.selectCount(queryWrapper);
//5.用户名不能重复
if(count_userAccount > 0){
throw new BusinessException(ErrorCode.UNAUTHORIZED,"用户名已被使用");
}
queryWrapper.eq("planetCode", planetCode);
long count_planetCode = userMapper.selectCount(queryWrapper);
//6.星球编号不能重复
if (count_planetCode > 0){
throw new BusinessException(ErrorCode.UNAUTHORIZED,"星球编号已存在");
}
//加密(盐值加密)
userPassword = DigestUtils.md5DigestAsHex((salt + userPassword).getBytes());
User user = new User();
user.setUserAccount(userAccount);
user.setUserPassword(userPassword);
user.setPlanetCode(planetCode);
if (! this.save(user)){
throw new BusinessException(ErrorCode.UNAUTHORIZED,"保存失败");
}
return user.getId();
}
用户登录:
有个参数HttpServletRequest request,是用来登陆后将用户脱敏后的信息保存到session中‘
@Override
public User userLogin(String userAccount, String userPassword, HttpServletRequest request) {
//1.校验
if (StringUtils.isAnyBlank(userAccount, userPassword)) {
throw new BusinessException(ErrorCode.UNAUTHORIZED,"参数为空");
}
if (userAccount.length()<4){
throw new BusinessException(ErrorCode.UNAUTHORIZED,"用户账号错误");
}
if (userPassword.length()<8 ){
throw new BusinessException(ErrorCode.UNAUTHORIZED,"用户密码错误");
}
//2.验证密码
String encryptPassword = DigestUtils.md5DigestAsHex((salt + userPassword).getBytes());
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userAccount", userAccount);
queryWrapper.eq("userPassword", encryptPassword);
User user = userMapper.selectOne(queryWrapper);
if (user == null){
log.info("用户不存在");
throw new BusinessException(ErrorCode.UNAUTHORIZED,"用户不存在");
}
//3.保存用户脱敏后的信息
User safetyUser = this.getSafetyUser(user);
request.getSession().setAttribute(USER_LOGIN_STATE, safetyUser);
return safetyUser;
}
用户脱敏:
public User getSafetyUser(User originUser){
if (originUser == null){
return null;
}
User safetyUser = new User();
safetyUser.setId(originUser.getId());
safetyUser.setUsername(originUser.getUsername());
safetyUser.setUserAccount(originUser.getUserAccount());
safetyUser.setAvatarUrl(originUser.getAvatarUrl());
safetyUser.setGender(originUser.getGender());
safetyUser.setPhone(originUser.getPhone());
safetyUser.setEmail(originUser.getEmail());
safetyUser.setPlanetCode(originUser.getPlanetCode());
safetyUser.setUserRole(originUser.getUserRole());
safetyUser.setUserStatus(originUser.getUserStatus());
safetyUser.setCreateTime(originUser.getCreateTime());
safetyUser.setTags(originUser.getTags());
return safetyUser;
}
浙公网安备 33010602011771号