Spring异常处理方案

1. 概述

主要主是将错误信息的错误码及描述信息保存到Properties文件中,然后提供工具类来读取这些错误信息并创建RestException。

涉及的类图如下:
Spring异常处理方案_第1张图片

2. 错误信息定义文件

# 角色
role.exists=S04M001,角色名称已存在
role.not.exists=S04M002,角色({})不存在

# 用户
user.username.not.exits=S05M001,用户名({})不存在
user.username.exists=S05M002,用户名已存在
user.id.not.exists=S05M003,指定编号({})的用户不存在
user.status.not.locked=S05M004,用户状态不是锁定状态,不需要解锁
user.status.not.approving=S05M005,用户状态不是待审批状态,不能进行审批
user.admin.cannot.beUnregisted=S05M006,管理员不能被注解

3. 异常枚举类的定义

public enum ErrorCodes {
    /**
     * 角色名称已存在
     */
    ROLE_EXISTS("role.exists"),

    /**
     * 指定名称的角色不存在
     */
    ROLE_NOT_EXISTS("role.not.exists"),

    /**
     * 用户名不存在
     */
    USER_USERNAME_NOT_EXISTS("user.username.not.exits"),

    /**
     * 用户名已存在
     */
    USER_USERNAME_EXISTS("user.username.exists"),

    /**
     * 指定编号的用户不存在
     */
    USER_ID_NOT_EXISTS("user.id.not.exists"),

    /**
     * 用户状态不是锁定状态,无需解锁
     */
    USER_STATUS_NOT_LOCKED("user.status.not.locked"),

    /**
     * 用户状态不是待审批状态,不能被审批
     */
    USER_STATUS_NOT_APPROVING("user.status.not.approving"),

    /**
     * 管理员不能被注销
     */
    USER_ADMIN_CANNOT_BE_REGISTED("user.admin.cannot.beUnregisted");

    private String errorName;
    ErrorCodes(String errorName) {
        this.errorName = errorName;
    }

    public String getErrorName() {
        return this.errorName;
    }
}

4. 异常类的定义

public class RestException extends Exception {
    private String code;
    private String message;
    private Throwable t;

    RestException(String code, String message) {
        this.code = code;
        this.message = message;
    }

    RestException(String code, String message, Throwable t) {
        this.code = code;
        this.message = message;
        this.t = t;
    }

    public String getCode() {
        return code;
    }

    public RestException setCode(String code) {
        this.code = code;
        return this;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public RestException setMessage(String message) {
        this.message = message;
        return this;
    }

    public Throwable getT() {
        return t;
    }

    public RestException setT(Throwable t) {
        this.t = t;
        return this;
    }
}

5. 异常辅助工具类

 public class ExceptionTool {
    private static final Logger logger = LoggerFactory.getLogger(ExceptionTool.class);
    private static Map errorInfoMap = new HashMap<>();

    private ExceptionTool() {

    }

    public static void init() throws IOException {
        DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource resource = resourceLoader.getResource("classpath:./errorCode.properties");
        Properties properties = new Properties();
        properties.load(resource.getInputStream());

        properties.forEach((o1, o2) -> {
            String errorName = o1.toString();
            String errorInfoStr = o2.toString();
            String[] strs = errorInfoStr.split(",");
            ErrorInfo errorInfo = new ErrorInfo();

            System.out.println(errorInfoStr);

            errorInfo.code = strs[0];
            errorInfo.message = strs[1];

            errorInfoMap.put(errorName, errorInfo);
        });
    }

    /**
     * 根据异常名称获取异常信息
     *
     * @return
     */
    public static RestException getException(ErrorCodes errorCodes, Object...parameters) {
        ErrorInfo errorInfo = errorInfoMap.get(errorCodes.getErrorName());
        String message = errorInfo.message;
        if (null != parameters && 0 != parameters.length) {
            for (Object obj: parameters) {
                if (!message.contains("{}")) {
                    break;
                }

                message = message.replaceFirst("\\{\\}", obj.toString());
            }
        }

        return new RestException(errorInfo.code, message);
    }

    public static RestException getException(Throwable t, ErrorCodes errorCodes, Object...parameters) {
        return getException(errorCodes, parameters).setT(t);
    }

    private static class ErrorInfo {
        private String code;
        private String message;
    }

    public static void main(String[] args) throws IOException {

    }
}

6. 使用

6.1 参数校验等无异常场景

User user = userDao.findByUsername(username);
if (null == user) {
    throw ExceptionTool.getException(ErrorCodes.USER_USERNAME_NOT_EXISTS, username);
}

6.2 捕获其它异常的场景

throw ExceptionTool.getException(exception, ErrorCodes.USER_USERNAME_NOT_EXISTS, username);  
// 或者不带参数:throw ExceptionTool.getException(exception, ErrorCodes.USER_USERNAME_NOT_EXISTS) 

你可能感兴趣的:(Spring)