SpringBoot 通用Error设计

在项目中需要设计统一的错误消息,通常使用枚举类定义“错误码”与“错误消息”;
并且也可以做错误消息自定义。

定义通过错误接口类:CommonError

public interface CommonError {

    // 获取错误码
    int getErrorCode();

    // 获取错误消息
    String getErrorMsg();

    // 设置错误消息,用于覆盖Enumeration中设置的默认错误消息
    CommonError setErrorMsg(String errorMsg);
}

定义错误枚举类:EnumError

/**
 * 继承至CommonError
 */
public enum EnumError implements CommonError {

    // 10000开头为通用错误类型
    UNKNOWN_ERROR(10001, "未知错误"),
    PARAMETER_VALIDATION_ERROR(10002, "参数不合法"),

    // 20000开头为用户信息相关错误码定义
    USER_NOT_EXIST(20001, "用户不存在"),
    USER_LOGIN_FAIL(20002, "用户名或密码错误"),
    USER_NOT_LOGIN(20003, "用户未登录"),

    // 定义错误码和错误消息字段
    private int errorCode;
    private String errorMsg;

    EnumError(int errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    @Override
    public int getErrorCode() {
        return errorCode;
    }

    @Override
    public String getErrorMsg() {
        return errorMsg;
    }

    // 主要的作用:可以修改错误码对应的errorMessage
    @Override
    public CommonError setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
        return this;
    }
}

定义业务异常类:BusinessException

/**
 * 包装器业务异常类实现模式
 */
public class BusinessException extends Exception implements CommonError {

    private CommonError commonError;

    // 通用构造器
    public BusinessException(CommonError commonError){
        super();
        this.commonError = commonError;
    }

    // 覆盖ErrorMessage的构造器
    public BusinessException(CommonError commonError, String errorMsg){
        super();
        this.commonError = commonError;
        this.commonError.setErrorMsg(errorMsg);
    }

    @Override
    public int getErrorCode() {
        return this.commonError.getErrorCode();
    }

    @Override
    public String getErrorMsg() {
        return this.commonError.getErrorMsg();
    }

    // 覆盖默认的errorMessage
    @Override
    public CommonError setErrorMsg(String errorMsg) {
        this.commonError.setErrorMsg(errorMsg);
        return this;
    }
}

在Controller中使用BusinessException:定义BaseController类

public class BaseController {

    // 定义ExceptionHandler解决未被Controller层吸收的exception
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public CommonReturnType exceptionHandler(Exception ex){
        Map<String, Object> responseData = new HashMap<>();
        if(ex instanceof BusinessException){
            BusinessException businessException = (BusinessException)ex;
            responseData.put("errorCode", businessException.getErrorCode());
            responseData.put("errorMsg", businessException.getErrorMsg());
        } else {
            responseData.put("errorCode", EnumBusinessError.UNKNOWN_ERROR.getErrorCode());
            responseData.put("errorMsg", EnumBusinessError.UNKNOWN_ERROR.getErrorMsg());
        }

        return CommonReturnType.create(responseData, "failed");
    }
}

在UserController中实现业务逻辑

// 用户登录接口
    @RequestMapping(value = "/login", method = RequestMethod.POST, consumes = "application/x-www-form-urlencoded")
    @ResponseBody
    public CommonReturnType login(@RequestParam(name = "username") String username,
                                  @RequestParam(name = "password") String password) throws BusinessException {
        // 第一步,入参校验
        if(StringUtils.isEmpty(username) || StringUtils.isEmpty(username)){
            throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR, "用户名和密码不能为空");
        }

        // 第二步,校验用户登录是否合法
        UserModel userModel = userService.validateLogin(username, PasswordEncrypt.encodeByMd5(password));

        // 第三步,加入到用户登录后的Session中
        this.httpServletRequest.getSession().setAttribute("IS_LOGIN", true);
        this.httpServletRequest.getSession().setAttribute("LOGIN_USER", userModel);

        return CommonReturnType.create(null);
    }
posted @ 2019-02-23 11:29  Vincen_shen  阅读(939)  评论(0编辑  收藏  举报