个人认为:如果不使用全局异常处理的话,那么会有很多异常都需要使用try catch进行捕获,重复代码增加,增加代码的恶心程度。
controller层代码:
@RestController
@RequestMapping(value = "/user")
public class UserController {
@Resource
private UserService userService;
@GetMapping(value = "get")
public R getUser(@RequestParam(name = "id") Integer id) throws BusinessException {
User user = userService.getUser(id);
if (user == null) {
throw new BusinessException(BusinessError.REQUEST_FAIL);
}
return R.common(new ErrorCode(BusinessError.REQUEST_SUCCESS.getErrCode(), BusinessError.REQUEST_SUCCESS.getErrMsg()));
}
}
当请求参数错误,tomcat层会返回一个400的状态码和一个页面
亦或是,输入一个不存在的请求路径,同样会返回一个页面,并且返回404状态码
给到前端也没有办法去进行解析。
因此需要定义一个公共的异常处理拦截器,对不同的异常不同处理,并返回统一个格式给到前端,让前端对其解析。
定义一个全局异常处理器:
可以使用@RestControllerAdvice+@ExceptionHandler结合使用;
如果使用@ControllerAdvice+@ExceptionHandler的话,还需要在每个异常处理的方法上加上@ResponseBody注解,否则返回的是页面。
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
//自定义的业务异常
@ExceptionHandler(BusinessException.class)
public R doError(BusinessException e){
log.error("BusinessException:{}",e);
return R.common(e.getErrorCode());
}
//请求路径找不到
@ExceptionHandler(NoHandlerFoundException.class)
public R doError(NoHandlerFoundException e){
log.error("NoHandlerFoundException:{}",e);
return R.common(new ErrorCode(BusinessError.NO_HANDLER_FOUNT.getErrCode(),BusinessError.NO_HANDLER_FOUNT.getErrMsg()));
}
//请求参数错误异常
@ExceptionHandler(MissingServletRequestParameterException.class)
public R doError(MissingServletRequestParameterException e){
log.error("MissingServletRequestParameterException:{}",e);
return R.common(new ErrorCode(BusinessError.BIND_EXCEPTION_ERROR.getErrCode(),BusinessError.BIND_EXCEPTION_ERROR.getErrMsg()));
}
//上面异常都未捕获到的话,就会被这个给捕获到
@ExceptionHandler(Exception.class)
public R doError(Exception e){
log.error("UNKNOWN:{}",e);
return R.common(new ErrorCode(BusinessError.UNKNOWN.getErrCode(),BusinessError.UNKNOWN.getErrMsg()));
}
}
加上全局异常处理器过后:测试