用户中心系统总结

用户中心系统

一.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;
    }
posted @ 2026-01-29 16:34  KaKaWlW  阅读(1)  评论(0)    收藏  举报