全局异常处理1-ControllerAdvice+ExceptionHandler

本文使用 @ControllerAdvice + @ExceptionHandler 进行全局的 Controller 层异常处理。只要设计得当,就再也不用在 Controller 层进行 try-catch 了!

 

一、经典案例

需求:希望通过全局统一的异常处理将自定义错误码以json的形式发送给前端。

 

1 统一返回结果类 ApiResult

首先,定义一个统一结果返回类,最终需要将这个结果类的内容返回给前端。

package com.suncl.test2spring.exception;

import lombok.Data;

@Data
public class ApiResult {

    private String code;

    private String msg;

    public ApiResult(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public ApiResult(ResultCode resultCode) {
        this.code = resultCode.getCode();
        msg = resultCode.getMsg();
    }

}

 

2 错误码枚举类 ResultCode

 

package com.suncl.test2spring.exception;

public enum  ResultCode {

    /**
     * 成功
     */
    SUCCESS("200", "success"),

    /**
     * 未知错误
     */
    BIZ_ERROR("505", "biz error"),

    /**
     * 未知错误
     */
    UNKNOWN_ERROR("504", "unkonwn error");


    /**
     * 结果码
     */
    private String code;

    /**
     * 结果码描述
     */
    private String msg;


    ResultCode(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

3 自定义业务异常类 BizException

 

package com.suncl.test2spring.exception;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BizException extends  RuntimeException {
    public BizException() {
    }
    public BizException(String message) {
        super(message);
        log.error(message);
    }
    public BizException(String message, Throwable cause) {
        super(message, cause);
        log.error(message);
    }
    public BizException(Throwable cause) {
        super(cause);
    }
}

 

4 定义全局异常处理类

  1. 通过 @ControllerAdvice 指定该类为 Controller 增强类。
  2. 通过 @ExceptionHandler 自定捕获的异常类型。
  3. 通过 @ResponseBody 返回 json 到前端。

 

package com.suncl.test2spring.exception;


import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 全局Controller层异常处理类-ControllerAdvice+ExceptionHandler 方式
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionResolver {
    /**
     * 处理所有不可知异常
     *
     * @param e 异常
     * @return json结果
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ApiResult handleException(Exception e) {
        // 打印异常堆栈信息
        log.error(e.getMessage(), e);
        return new ApiResult(ResultCode.UNKNOWN_ERROR);
    }
    /**
     * 处理所有业务异常
     *
     * @param e 业务异常
     * @return json结果
     */
    @ExceptionHandler(BizException.class)
    @ResponseBody
    public ApiResult handleOpdRuntimeException(BizException e) {
        // 不打印异常堆栈信息
        log.error(e.getMessage(),e);
        return new ApiResult(ResultCode.BIZ_ERROR.getCode(),e.getMessage());
    }
}

 

5 测试

上述写法对于系统中抛出的 

throw new RuntimeException("未知异常出现了");

返回结果为 {"code":"504","msg":"unkonwn error"}

throw new BizException("用户id不可为空");

返回结果为 {"msg":"用户id不可为空","code":"505"}

posted @ 2020-01-20 10:33  reload  阅读(251)  评论(0编辑  收藏  举报