SpringBoot全局异常拦截

SpringBoot全局异常捕获

使用到的技能

  1. @RestControllerAdvice或(@ControllerAdvice+@ResponseBody)
  2. @ExceptionHandler

代码实现

  1. 统一返回入口
  2. 自定义异常
  3. 全局异常处理

统一返回入口Result

/**
 * @ClassName Result
 * @Description 统一返回格式
 * @Author chaoba
 * @Version V1.0
 */
 @Data
public class Result<T> {
    private int code;
    private String msg;
    private T data;

    /**
     * 成功时候的调用
     */
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<T>(CodeMsg.SUCCESS);
        result.setData(data);
        return result;
    }

    /**
     * 成功时候的调用
     */
    public static <T> Result<T> successMsg(String msg) {
        return new Result<T>(200, msg);
    }

    /**
     * 失败时候的调用
     */
    public static <T> Result<T> errorCodeMsg(CodeMsg codeMsg) {
        return new Result<T>(codeMsg);
    }

    /**
     * 成功时候的调用
     */
    public static <T> Result<T> successCodeMsg(CodeMsg codeMsg) {
        return new Result<T>(codeMsg);
    }

    public static <T> Result<T> error(T data) {
        Result<T> result = new Result<T>(CodeMsg.FAIL);
        result.setData(data);
        return result;
    }

    /**
     * 失败时候的调用
     */
    public static <T> Result<T> errorMsg(String msg) {
        return new Result<T>(0, msg);
    }

    /**
     * 全部参数
     *
     * @param
     * @param <T>
     * @return
     */
    public static <T> Result<T> getResult() {
        return new Result<T>();
    }

    public static <T> Result<T> toAjaxResult(int rows) {
        return rows > 0 ? success(null) : error(null);
    }

    public static <T> Result<T> toAjaxResult(boolean rows) {
        return rows ? success(null) : error(null);
    }

    private Result(T data) {
        this.data = data;
    }

    private Result() {
    }

    private Result(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }


    private Result(CodeMsg codeMsg) {
        if (codeMsg != null) {
            this.code = codeMsg.getCode();
            this.msg = codeMsg.getMsg();
        }
    }

}

自定义异常

/**
 * @ClassName GlabalException
 * @Description 全局异常
 * @Author chaoba
 * @Version V1.0
 */
@Data
public class GlabalException extends RuntimeException {
    //错误状态码
    private int code;

    public GlabalException(int code) {
        this.code = code;
    }

    public GlabalException(String message, int code) {
        super(message);
        this.code = code;
    }

    public GlabalException(CodeMsg codeMsg) {
        super(codeMsg.getMsg());
        this.code = codeMsg.getCode();
    }

    public GlabalException(String message) {
        super(message);
    }

    public GlabalException(Throwable cause, int code) {
        super(cause);
        this.code = code;
    }

    public GlabalException(GlabalException ex) {
        super(ex);

    }
}

全局异常处理

/**
 * @ClassName GlabalExceptionHandler
 * @Description 全局异常拦截,只提供接口-无需页面404等错误
 * @Author chaoba
 * @Version V1.0
 */
@RestControllerAdvice
public class GlabalExceptionHandler {
    //拦截自定义异常
    @ExceptionHandler(value = GlabalException.class)
    public Result jsonErrorHandler(GlabalException e) {
        Result<Object> result = Result.getResult();
        result.setMsg(e.getMessage());
        result.setCode(e.getCode());
        result.setData(null);
        return result;
    }
	//拦截全部异常
    @ExceptionHandler(value = Exception.class)
    public Result systemJsonErrorHandler(Exception e) {
        e.printStackTrace();
        if (e instanceof NoHandlerFoundException) {
            return Result.errorCodeMsg(CodeMsg.NOT_FOUND);
        } else if (e instanceof MissingServletRequestParameterException) {
            //get请求参数异常,不能为空异常---Query中缺少必要的参数。
            Result<Object> objectResult = Result.errorCodeMsg(CodeMsg.METHOD_ARG_TYPE_EXCEPTION);
            objectResult.setMsg("参数 " + ((MissingServletRequestParameterException) e).getParameterName() + "不能为空");
            return objectResult;

        } else if (e instanceof MethodArgumentNotValidException) {
            //参数校验
            MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
            FieldError fieldError = ex.getBindingResult().getFieldErrors().get(0);
            Result<Object> objectResult = Result.errorCodeMsg(CodeMsg.METHOD_ARG_TYPE_EXCEPTION);
            objectResult.setMsg(fieldError.getField() + "  " + fieldError.getDefaultMessage());
            return objectResult;
        } else if (e instanceof MethodArgumentTypeMismatchException) {
            // @RequestParam  参数类型错误
            Result<Object> objectResult = Result.errorCodeMsg(CodeMsg.METHOD_ARG_TYPE_EXCEPTION);
            MethodArgumentTypeMismatchException ex = (MethodArgumentTypeMismatchException) e;
            if (ex.getName() != null && !ex.getName().isEmpty()) {
                objectResult.setMsg("参数 " + ex.getName() + " 类型错误");
            }
            return objectResult;

        } else if (e instanceof HttpMessageNotReadableException) {
            //传参类型导致请求参数异常---content_type导致的异常
            return Result.errorCodeMsg(CodeMsg.METHOD_ARG_TYPE_EXCEPTION);
        } else if (e instanceof HttpRequestMethodNotSupportedException) {
            //客户端使用的请求方法不被该接口支持。请求方式错了
            return Result.errorCodeMsg(CodeMsg.HTTP_REQUEST_METHOD_NOT_SUPPORTED);
        } else if (e instanceof DuplicateKeyException) {
            return Result.errorCodeMsg(CodeMsg.EXIST);
        } else if (e instanceof MySQLIntegrityConstraintViolationException) {
            return Result.errorCodeMsg(CodeMsg.EXIST);
        }

        return Result.errorCodeMsg(CodeMsg.SERVER_EXCEPTION);
    }

}
一万年太久,只争朝夕!
原文地址:https://www.cnblogs.com/chaoba/p/14204069.html