(二)全局异常处理

背景:

常见代码中使用try&&catch捕获处理异常,仅针对代码块。若没有全局异常处理,系统出现未处理的异常时会直接返异常信息,影响用户体验。

(一)定义异常信息

定义异常信息操作接口

public interface BaseErrorInfoInterface {
    public String getResultCode();
    public String getResultMessage();
}

定义枚举类封装系统常见异常信息,实现异常信息操作接口

public enum BaseErrorEnum implements BaseErrorInfoInterface{
    SUCCESS("200","操作成功!"),
    FAIL("500","操作失败!"),
    INTERNAL_SERVER_ERROR("500", "服务器内部错误!"),
    BODY_NOT_MATCH("400","请求数据格式不合规!"),
    NOT_FOUND("404", "未找到该资源!"),
    SERVER_BUSY("503","服务器正忙,请稍后再试!")
    ;

    private String resultCode;
    private String resultMessage;

    BaseErrorEnum( String resultCode, String resultMessage) {
        this.resultCode = resultCode;
        this.resultMessage = resultMessage;
    }

    @Override
    public String getResultCode() {
        return resultCode;
    }

    @Override
    public String getResultMessage() {
        return resultMessage;
    }
}

(二)自定义异常,继承运行时异常。新增带参构造函数,方便使用自定义的异常信息。

public class BizException extends RuntimeException{
    /**
     * 错误码
     */
    protected String errorCode;
    /**
     * 错误信息
     */
    protected String errorMsg;

    public BizException() {
        super();
    }

    public BizException(BaseErrorInfoInterface errorInfoInterface) {
        super(errorInfoInterface.getResultCode());
        this.errorCode = errorInfoInterface.getResultCode();
        this.errorMsg = errorInfoInterface.getResultMessage();
    }

    public BizException(BaseErrorInfoInterface errorInfoInterface, Throwable cause) {
        super(errorInfoInterface.getResultCode(), cause);
        this.errorCode = errorInfoInterface.getResultCode();
        this.errorMsg = errorInfoInterface.getResultMessage();
    }

    public BizException(String errorMsg) {
        super(errorMsg);
        this.errorMsg = errorMsg;
    }

    public BizException(String errorCode, String errorMsg) {
        super(errorCode);
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    public BizException(String errorCode, String errorMsg, Throwable cause) {
        super(errorCode, cause);
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }


    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    @Override
    public Throwable fillInStackTrace() {
        return this;
    }

}

(三)定义返回消息体,定义常用的状态方法

public class ReturnDTO  {
    private Object message;
    private String code;
    private String desc;
    public ReturnDTO() {
    }
    public ReturnDTO(BaseErrorInfoInterface errorInfo) {
        this.code = errorInfo.getResultCode();
        this.message = errorInfo.getResultMessage();
    }

    public Object getMessage() {
        return message;
    }

    public void setMessage(Object message) {
        this.message = message;
    }

    public String getCode() {
        return code;
    }

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

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    /**
     * 成功
     *
     * @return
     */
    public static ReturnDTO success() {
        return success(null);
    }

    /**
     * 成功
     * @param data
     * @return
     */
    public static ReturnDTO success(Object data) {
        ReturnDTO rb = new ReturnDTO();
        rb.setCode(BaseErrorEnum.SUCCESS.getResultCode());
        rb.setDesc(BaseErrorEnum.SUCCESS.getResultMessage());
        rb.setMessage(data);
        return rb;
    }

    /**
     * 失败
     */
    public static ReturnDTO error(BaseErrorInfoInterface errorInfo) {
        ReturnDTO rb = new ReturnDTO();
        rb.setCode(errorInfo.getResultCode());
        rb.setDesc(errorInfo.getResultMessage());
        rb.setMessage(null);
        return rb;
    }

    /**
     * 失败
     */
    public static ReturnDTO error(String code, String message) {
        ReturnDTO rb = new ReturnDTO();
        rb.setCode(code);
        rb.setDesc(message);
        rb.setMessage(null);
        return rb;
    }

    /**
     * 失败
     */
    public static ReturnDTO error( String message) {
        ReturnDTO rb = new ReturnDTO();
        rb.setCode("500");
        rb.setDesc(message);
        rb.setMessage(null);
        return rb;
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this);
    }
}

(四)定义全局异常处理类,注意理解使用注解@ControllerAdvice

@ControllerAdvice
public class ExceptionHandler {

    /**
     * 处理自定义的业务异常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = BizException.class)
    @ResponseBody
    public ReturnDTO bizExceptionHandler(HttpServletRequest req, BizException e){
        log.error("全局异常捕获-发生的业务异常是:{}",e.getErrorMsg());
        return ReturnDTO.error(e.getErrorCode(),e.getErrorMsg());
    }
    /**
     * 处理空指针的异常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = NullPointerException.class)
    @ResponseBody
    public ReturnDTO nullPointExceptionHandler(HttpServletRequest req,NullPointerException e){
        log.error("全局异常捕获-空指针异常是:",e);
        return ReturnDTO.error(BaseErrorEnum.INTERNAL_SERVER_ERROR);
    }
    /**
     * 处理其他异常
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value =Exception.class)
    @ResponseBody
    public ReturnDTO exceptionHandler(HttpServletRequest req, Exception e){
        log.error("全局异常捕获-未知异常!原因是:",e);
        return ReturnDTO.error(BaseErrorEnum.INTERNAL_SERVER_ERROR);
    }

}

测试方法

    public void test01(){
         //触发自定义异常
         throw new BizException(BaseErrorEnum.BODY_NOT_MATCH);
        //触发空指针异常
		String str = null;
        str.equals("111");
        //触发其他异常
		String str2 = "123abc";
        Integer.parseInt(str2);
    }
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值