一、全局异常处理
SpringBoot给我们提供了@ControllerAdvice和 @ExceptionHandler注解
注解的作用:
@ControllerAdvice用来开启全局的异常捕获,
@ExceptionHandler用来说明捕获哪些异常,并对这些捕获的异常进行处理。
二、具体代码样例
@RestControllerAdvice意味着当前类可以用作全局的异常处理器。
handleException
方法是一个异常处理器,使用 @ExceptionHandler(value = Exception.class)
注解标记。这意味着这个方法会处理所有从控制器方法抛出的 Exception
类型的异常(或其子类)。
方法参数包括一个 Exception
对象(捕获的异常)和一个 HttpServletRequest
对象(当前的HTTP请求)。
@RestControllerAdvice //全局异常处理器
@Slf4j
public class GlobalExceptionHandlerController extends BaseController {
@ExceptionHandler(value = Exception.class)
@ResponseBody
Object handleException(Exception e, HttpServletRequest request) {
log.info("请求错误,请求地址{},错误信息:", request.getRequestURL(), e);
ResponseVO response = new ResponseVO();
//404
if (e instanceof NoHandlerFoundException) {
response.setCode(ResponseCodeEnum.CODE_404.getCode());
response.setInfo(ResponseCodeEnum.CODE_404.getMsg());
response.setStatus(Constants.STATUC_ERROR);
} else if (e instanceof BusinessException) {
//业务错误
BusinessException biz = (BusinessException) e;
response.setCode(biz.getCode());
if (biz.getCode() == null) {
response.setCode(ResponseCodeEnum.CODE_600.getCode());
}
response.setInfo(biz.getMessage());
response.setStatus(Constants.STATUC_ERROR);
} else if (e instanceof BindException) {
//参数类型错误
response.setCode(ResponseCodeEnum.CODE_600.getCode());
response.setInfo(ResponseCodeEnum.CODE_600.getMsg());
response.setStatus(Constants.STATUC_ERROR);
} else if (e instanceof DuplicateKeyException) {
//主键冲突
response.setCode(ResponseCodeEnum.CODE_601.getCode());
response.setInfo(ResponseCodeEnum.CODE_601.getMsg());
response.setStatus(Constants.STATUC_ERROR);
} else {
response.setCode(ResponseCodeEnum.CODE_500.getCode());
response.setInfo(ResponseCodeEnum.CODE_500.getMsg());
response.setStatus(Constants.STATUC_ERROR);
}
return response;
}
}
异常处理逻辑
- 首先,使用 log.info 记录异常信息,包括请求的URL和异常详情。
- 创建一个
ResponseVO
对象,用于构建返回给客户端的响应。 - 使用
if-else
语句对不同类型的异常进行不同的处理:NoHandlerFoundException
: 当没有合适的处理器方法处理请求时抛出。返回404错误码。BusinessException
: 业务逻辑异常。返回业务错误码和错误信息。BindException
: 参数绑定异常(例如,请求参数类型不匹配)。返回600错误码。DuplicateKeyException
: 数据库主键冲突异常。返回601错误码。- 其他异常: 默认情况下,返回500错误码。
- 在每种情况下,都设置
ResponseVO
对象的code
、info
和status
属性,然后返回这个对象。
三、总结
通过这种方式,当控制器中发生异常时,这个全局异常处理器会捕获这些异常,统一处理,并返回一个格式化的错误响应给客户端。这有助于保持API的一致性,并提供友好的错误提示信息。