個人認爲:如果不使用全局異常處理的話,那麼會有很多異常都需要使用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()));
}
}
加上全局異常處理器過後:測試