实现思路
- 使用@RestControllerAdvice注解,定义系统全局异常捕捉类,捕捉系统全局异常
- 继承RuntimeException类,定义业务异常类,用于业务打断
异常捕捉演示
- 下载源代码,github源码链接
- 项目启动,调用/test/exception接口
- 自定义异常

- 全局异常捕捉

关键业务代码
- 系统全局异常捕捉
/**
* 系统全局异常捕捉
*/
@Slf4j
@RestControllerAdvice
public class GlobalControllerExceptionHandler {
@ExceptionHandler(ErrorCodeException.class)
@ResponseBody
public ResultBean handleErrorCodeException(ErrorCodeException e) {
Integer code = e.getErrorCode();
String msg = e.getMessage();
// 外部传入了消息描述,这个地方就不再覆盖了
if (!StringUtils.hasLength(msg)) {
msg = "服务器正忙,请稍后重试。";
}
if (e instanceof BusinessException) {
log.info("Business exception : msg {} : code {}", msg, code);
} else {
log.error("ErrorCodeException exception : msg {}", msg, e);
}
return ResultBean.error(code, msg);
}
/**
* 空指针
*/
@ExceptionHandler(value = NullPointerException.class)
@ResponseBody
public ResultBean nullPointerException(NullPointerException e) {
log.error("发生空指针异常!原因是:", e);
return ResultBean.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.toString());
}
/**
* 类型强制转换异常
*/
@ExceptionHandler(value = ClassCastException.class)
@ResponseBody
public ResultBean classCastException(ClassCastException e) {
log.error("类型强制转换异常!原因是:", e);
return ResultBean.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.toString());
}
/**
* 数组下标越界异常
*/
@ExceptionHandler(value = ArrayIndexOutOfBoundsException.class)
@ResponseBody
public ResultBean arrayIndexOutOfBoundsException(ArrayIndexOutOfBoundsException e) {
log.error("数组下标越界异常!原因是:", e);
return ResultBean.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.toString());
}
/**
* 字符串转换为数字异常
*/
@ExceptionHandler(value = NumberFormatException.class)
@ResponseBody
public ResultBean numberFormatException(NumberFormatException e) {
log.error("字符串转换为数字异常!原因是:", e);
return ResultBean.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.toString());
}
/**
* 输入输出异常
*/
@ExceptionHandler(value = IOException.class)
@ResponseBody
public ResultBean IOException(IOException e) {
log.error("输入输出异常!原因是:", e);
return ResultBean.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.toString());
}
/**
* 方法未找到异常
*/
@ExceptionHandler(value = NoSuchMethodException.class)
@ResponseBody
public ResultBean noSuchMethodException(NoSuchMethodException e) {
log.error("方法未找到异常!原因是:", e);
return ResultBean.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.toString());
}
/**
* 系统异常
*/
@ExceptionHandler(value = SystemException.class)
@ResponseBody
public ResultBean systemException(SystemException e) {
log.error("系统异常!原因是:", e);
return ResultBean.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.toString());
}
/**
* 非法参数异常
*/
@ExceptionHandler(value = IllegalArgumentException.class)
@ResponseBody
public ResultBean IllegalArgumentException(IllegalArgumentException e) {
log.error("非法参数异常!原因是:", e);
return ResultBean.error(HttpStatus.BAD_REQUEST.value(), e.toString());
}
/**
* 不支持的操作异常
*/
@ExceptionHandler(value = UnsupportedOperationException.class)
@ResponseBody
public ResultBean unsupportedOperationException(UnsupportedOperationException e) {
log.error("不支持的操作异常!原因是:", e);
return ResultBean.error(HttpStatus.BAD_REQUEST.value(), e.toString());
}
/**
* 操作数据库异常
*/
@ExceptionHandler(value = SQLException.class)
@ResponseBody
public ResultBean sqlException(SQLException e) {
log.error("操作数据库异常!原因是:", e);
return ResultBean.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.toString());
}
/**
* 参数校验失败
*/
@ExceptionHandler(BindException.class)
@ResponseBody
public ResultBean handlerConstraintViolationException(BindException e) {
log.warn(e.getMessage(), e);
if (!e.getAllErrors().isEmpty()) {
String msg = e.getAllErrors().get(0).getDefaultMessage();
return ResultBean.error(HttpStatus.BAD_REQUEST.value(), msg);
} else {
return ResultBean.error(HttpStatus.BAD_REQUEST.value(), e.toString());
}
}
/**
* 方法参数无效异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResultBean handlerArgumentNotValidException(MethodArgumentNotValidException e) {
log.warn(e.getMessage(), e);
if (!e.getBindingResult().getAllErrors().isEmpty()) {
String msg = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
return ResultBean.error(HttpStatus.BAD_REQUEST.value(), msg);
} else {
return ResultBean.error(HttpStatus.BAD_REQUEST.value(), e.toString());
}
}
/**
* Internal Server Error 500
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ResultBean handlerException(Exception e) {
log.error(e.getMessage(), e);
return ResultBean.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.toString());
}
/**
* 404异常
*/
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ResultBean noHandlerFoundException(NoHandlerFoundException e) {
return ResultBean.error(HttpStatus.NOT_FOUND.value(), e.toString());
}
}
本文定义了常见的全局异常,有兴趣的小伙伴,可以根据业务增加其他的异常。
- 业务异常类,用于业务打断
/**
* 业务异常类,只用于业务打断
*/
public class BusinessException extends ErrorCodeException {
private static final long serialVersionUID = -45155154531465551L;
public BusinessException(Integer businessErrorCode) {
super(businessErrorCode);
}
public BusinessException(Integer businessErrorCode, String message, Throwable cause) {
super(businessErrorCode, message, cause);
}
public BusinessException(Integer businessErrorCode, String message) {
super(businessErrorCode, message);
}
public BusinessException(Integer businessErrorCode, Throwable cause) {
super(businessErrorCode, cause);
}
public BusinessException(Integer businessErrorCode, String message, Object result) {
super(businessErrorCode, message, result);
}
public BusinessException(ResultCode resultCode) {
this(resultCode.getCode(), resultCode.getMsg());
}
public BusinessException(ResultCode resultCode, Throwable cause) {
this(resultCode.getCode(), resultCode.getMsg(), cause);
}
public static void throwException(ResultCode resultCode) {
throw new BusinessException(resultCode);
}
public static void throwException(ResultCode resultCode,Throwable cause) {
throw new BusinessException(resultCode, cause);
}
@Override
public String getMessage() {
return super.getMessage();
}
}
/**
* 含错误码的异常类
*/
public class ErrorCodeException extends RuntimeException {
private static final long serialVersionUID = -21116129021561225L;
// 错误码
private Integer errorCode;
// 异常结果返回
private Object result;
public ErrorCodeException(Integer errorCode) {
this(errorCode, null, null);
}
public ErrorCodeException(Integer errorCode, String message) {
this(errorCode, message, null);
}
public ErrorCodeException(Integer errorCode, Throwable cause) {
this(errorCode, null, cause);
}
public ErrorCodeException(Integer errorCode, String message, Throwable cause) {
super(message, cause);
this.errorCode = errorCode;
}
public ErrorCodeException(Integer errorCode, String message,Object result) {
super(message);
this.errorCode = errorCode;
this.result = result;
}
public Integer getErrorCode() {
return errorCode;
}
@Override
public String getMessage() {
return super.getMessage();
}
public Object getResult(){
return this.result;
}
}
- 异常捕捉测试类
@Service
public class TestServiceImpl implements TestService {
@Override
public ResultBean test(int type) {
if (1 == type) {
throw new BusinessException(ResultCode.INTERNAL_SERVER_ERROR);
} else if (2 == type) {
int a = 1 / 0;
} else if (3 == type) {
Integer[] arr = {1, 2};
int a = arr[2];
} else if (4 == type) {
List<Integer> list = new ArrayList<>();
list.add(1);
int a = list.get(2);
} else if (5 == type) {
String a = "12.5662";
Integer b = Integer.parseInt(a);
} else if (6 == type) {
Map<String, Object> map = null;
map.size();
} else if (7 == type) {
String a = "hello world";
Map map = JSON.parseObject(a, Map.class);
} else if (8 == type) {
List<String> list = null;
list.contains("a");
} else if (9 == type) {
Integer[] arr = new Integer[1];
arr[0] = 1;
arr[1] = 2;
} else {
int a = 1 + 1;
}
return ResultBean.success();
}
}

