自定义运行时异常设计(RuntimeException)


在每个公司的架构中,日志肯定是重点,以至于很多时候需要对日志进行优化!

那么该怎么设计,怎么定义自己想提示出的自定义消息呢,下面就是一个很好的设计示例,以供参考!


本文采取从上到下的模式用代码设计:


1. 自定义异常根类:

/**
 * 公司的运行时异常根类。【这个类可以打进jar包,供全公司使用】
 *
 * <p>
 * 统一异常层次,便于处理与监控。
 *
 * @author 
 *
 */
public class CompanyRuntimeException extends RuntimeException {
    /** serialVersionUID */
    private static final long serialVersionUID = 0L;

    /** 严重级别 */
    protected int severity = CompanyExceptionSeverity.NORMAL;

    /**
     * 空构造器。
     */
    public CompanyRuntimeException() {
        super();
    }

    /**
     * 构造器。
     *
     * @param severity 严重级别
     */
    public CompanyRuntimeException(int severity) {
        super();

        this.severity = severity;
    }

    /**
     * 构造器。
     *
     * @param message 消息
     */
    public CompanyRuntimeException(String message) {
        super(message);
    }

    /**
     * 构造器。
     *
     * @param message 消息
     * @param severity 严重级别
     */
    public CompanyRuntimeException(String message, int severity) {
        super(message);

        this.severity = severity;
    }

    /**
     * 构造器。
     *
     * @param cause 原因
     */
    public CompanyRuntimeException(Throwable cause) {
        super(cause);
    }

    /**
     * 构造器。
     *
     * @param cause 原因
     * @param severity 严重级别
     */
    public CompanyRuntimeException(Throwable cause, int severity) {
        super(cause);

        this.severity = severity;
    }

    /**
     * 构造器。
     *
     * @param message 消息
     * @param cause 原因
     */
    public CompanyRuntimeException(String message, Throwable cause) {
        super(message, cause);
    }

    /**
     * 构造器。
     *
     * @param message 消息
     * @param cause 原因
     * @param severity 严重级别
     */
    public CompanyRuntimeException(String message, Throwable cause, int severity) {
        super(message, cause);

        this.severity = severity;
    }

    /**
     * @return Returns the severity.
     */
    public int getSeverity() {
        return severity;
    }

    /**
     * @see java.lang.Throwable#toString()
     */
    public String toString() {
        StringBuffer buffer = new StringBuffer();

        buffer.append(super.toString()).append(" - severity: ");

        switch (severity) {
            case CompanyExceptionSeverity.MINOR:
                buffer.append("MINOR");
                break;

            case CompanyExceptionSeverity.NORMAL:
                buffer.append("NORMAL");
                break;

            case CompanyExceptionSeverity.MAJOR:
                buffer.append("MAJOR");
                break;

            case CompanyExceptionSeverity.CRITICAL:
                buffer.append("CRITICAL");
                break;

            default:
                buffer.append("UNKNOWN");
        }

        buffer.append("(").append(severity).append(")");

        return buffer.toString();
    }
}

异常级别分类:

/**
 * 异常严重级别常量。
 *
 * @author 
 *
 * @version 
 */
public interface CompanyExceptionSeverity {
    /** 轻微 */
    int MINOR = 1;

    /** 一般 */
    int NORMAL = 2;

    /** 重要 */
    int MAJOR = 3;

    /** 严重 */
    int CRITICAL = 4;
}


2. 每个业务的自定义异常类,例如MyPayException【自定义的测试业务】

/**
 * 自定义系统运行时异常
 *
 * @author 
 * @version 
 */
public class MyPayException extends CompanyRuntimeException {

    /** serialVersionUID */
    private static final long      serialVersionUID = 0L;

    /** 返回码 */
    private MyPayResultCodeEnum resultCode;

    /**
     * 构造函数
     * 
     * @param resultCode    返回码
     */
    public MyPayException(MyPayResultCodeEnum resultCode) {
        super();
        this.resultCode = resultCode;
    }

    /**
     * 构造函数
     * 
     * @param resultCode    返回码
     * @param e             需要传递的异常
     */
    public MyPayException(MyPayResultCodeEnum resultCode, Throwable e) {
        super(e);
        this.resultCode = resultCode;
    }

    /**
     * 构造函数
     * 
     * @param resultCode    返回码
     * @param message       错误信息
     */
    public MyPayException(MyPayResultCodeEnum resultCode, String message) {
        super(message);
        this.resultCode = resultCode;
    }

    @Override
    public String toString() {//ToStringBuilder ToStringStyle所属于commons-lang jar包
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }

    /*
     * getter and setter
     */
    public MyPayResultCodeEnum getResultCode() {
        return resultCode;
    }

    public void setResultCode(MyPayResultCodeEnum resultCode) {
        this.resultCode = resultCode;
    }

}

3.业务异常信息枚举

/**
 * 自定义业务操作返回码枚举
 *
 * @author 
 * @version $
 */
public enum MyPayResultCodeEnum {

    /** 操作成功 */
    SUCCESS("SUCCESS", "操作成功"),

    /** 系统错误 */
    SYSTEM_FAILURE("SYSTEM_FAILURE", "系统错误"),

    /** 参数为空 */
    NULL_ARGUMENT("NULL_ARGUMENT", "参数为空"),

    /** 参数不正确 */
    ILLEGAL_ARGUMENT("ILLEGAL_ARGUMENT", "参数不正确"),

    /** 邮箱非法 */
    EMAIL_ILLEGAL("EMAIL_ILLEGAL", "邮箱非法")

    ;
    /** 枚举值 */
    private String value;

    /** 枚举信息 */
    private String message;

    private MyPayResultCodeEnum(String value, String message) {
        this.value = value;
        this.message = message;
    }

    /**
     * 根据枚举值获取枚举对象,如果找不到对应的枚举返回<code>null</code>
     *
     * @param value 枚举值
     * @return 枚举对象
     */
    public static MyPayResultCodeEnum getEnumByValue(String value) {
        for (MyPayResultCodeEnum resultCode : MyPayResultCodeEnum.values()) {
            if (resultCode.getValue().equals(value)) {
                return resultCode;
            }
        }
        return null;
    }

    /*
     * getter
     */
    public String getValue() {
        return value;
    }

    public String getMessage() {
        return message;
    }

}


4.业务执行捕获异常

public <T> T execute(){
        MyPayResult retResult = new MyPayResult();
        try {
            // 1.业务校验
            // 2.业务执行
            // 3.异常处理
        } catch (MyPayException e) {
            retResult.setSuccess(false);
            retResult.setResultCode(e.getResultCode());
            retResult.setMessage(StringUtil.isNotBlank(e.getMessage()) ? e.getMessage() : e
                .getResultCode().getMessage());
            logger.warn("业务异常," + e.getResultCode().getMessage(), e);
        }
        
        return (T)retResult;
    }

5.第4中的返回值定义,以供调用端判断是否执行成功还是失败:

import java.io.Serializable;


/**
 * 订购中心业务处理结果
 *
 * @author 
 * @version 
 */
public class MyPayResult implements Serializable {

    /** serialVersionUID */
    private static final long      serialVersionUID = 1L;

    /** 成功标志 */
    protected boolean              success;

    /** 返回码 */
    private MyPayResultCodeEnum resultCode;

    /** 返回信息 */
    protected String               message;

    /**
     * 构造函数,默认返回码为“SUCCESS”。
     */
    public MyPayResult() {
        resultCode = MyPayResultCodeEnum.SUCCESS;
        this.message = resultCode.getMessage();
        success = true;
    }

    /**
     * 构造函数
     * 
     * @param success 成功标志
     */
    public MyPayResult(boolean success) {
        this.success = success;
        this.resultCode = MyPayResultCodeEnum.SYSTEM_FAILURE;
        this.message = resultCode.getMessage();
    }

    /**
     * 构造函数
     * 
     * @param resultCode 返回码
     */
    public MyPayResult(MyPayResultCodeEnum resultCode) {
        success = resultCode == MyPayResultCodeEnum.SUCCESS;
        this.resultCode = resultCode;
        this.message = resultCode.getMessage();
    }

    /**
     * 构造函数
     * 
     * @param resultCode 返回码
     */
    public MyPayResult(boolean success, MyPayResultCodeEnum resultCode) {
        this.success = success;
        this.resultCode = resultCode;
        this.message = resultCode.getMessage();
    }

    /**
     * 返回结果信息
     *
     * @return 如果resultCode存在,返回resultCode的message,否则返回result中的message字段
     */
    public String findMessage() {
        return StringUtil.isNotBlank(message) ? message : resultCode.getMessage();
    }

    /*
     * getters and setters
     */

    /**
     * Getter method for property <tt>success</tt>.
     * 
     * @return property value of success
     */
    public boolean isSuccess() {
        return success;
    }

    /**
     * Setter method for property <tt>success</tt>.
     * 
     * @param success value to be assigned to property success
     */
    public void setSuccess(boolean success) {
        this.success = success;
    }

    /**
     * Getter method for property <tt>resultCode</tt>.
     * 
     * @return property value of resultCode
     */
    public MyPayResultCodeEnum getResultCode() {
        return resultCode;
    }

    /**
     * Setter method for property <tt>resultCode</tt>.
     * 
     * @param resultCode value to be assigned to property resultCode
     */
    public void setResultCode(MyPayResultCodeEnum resultCode) {
        this.resultCode = resultCode;
    }

    /**
     * Getter method for property <tt>message</tt>.
     * 
     * @return property value of message
     */
    public String getMessage() {
        return message;
    }

    /**
     * Setter method for property <tt>message</tt>.
     * 
     * @param message value to be assigned to property message
     */
    public void setMessage(String message) {
        this.message = message;
    }

    /** 
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
    
}


6.使用范例:校验邮箱是否合法(可以放到工具类util)

/** Email验证正则表达式 */
    private static final String REGEX_EMAIL = "^(([_\\w-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([_\\w-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?))$";

/**
     * 验证邮件地址格式
     *
     * @param email                 字符串
     * @param message               错误信息
     * @exception MyPayException 如果邮件格式不正确
     */
    public static void notEmail(String email, String message) {
        if (!StringUtil.isEmpty(email) && !Pattern.compile(REGEX_EMAIL).matcher(email).find()) {
            throw new MyPayException(MyPayResultCodeEnum.EMAIL_ILLEGAL, message);
        }
    }



以上,设计有需要改进的地方,欢迎探讨!!!!



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值