在日常項目中寫代碼時經常會有需要返回錯誤信息的代碼,如下:
public Result demo() {
Demo demo = demoRepository.getDemo();
if (demo != null) {
return new Result(CommonCode.SUCCESS, demo);
} else {
return new Result(CommonCode.FAIL, null);
}
}
上面的代碼會有一些缺陷:
- 上邊的代碼只要操作不成功僅向用戶返回統一的失敗信息,無法區別具體的錯誤信息。
- 在方法中如果有異常該如何捕獲,在項目中是service層還是controller層try/catch,無論在哪裏進行異常捕獲都會造成代碼冗餘,不易維護。
解決
- 在項目中判斷校驗失敗時,直接拋出具體業務異常。
- 使用統一異常捕獲類,向用戶返回統一規範的響應信息。
解決步驟
- 編寫統一異常類
這裏繼承RuntimeException沒有繼承Exception是因爲java所有方法默認throw了RuntimeExceptin,這樣在進行代碼優化時不用重新throw
public class UnityException extends RuntimeException{
private Result result;
public UnityException(Result result) {
this.result = result;
}
public Result getResult(){
return this.result;
}
}
- 異常捕獲類
這裏的ControllerAdvice相當於controller的增強,ExceptionHandler註解在springmvc異常處理時被識別,然後執行。這樣可以實現全局異常處理
@ControllerAdvice
public class ExceptionCatch {
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);
/**
* 識別拋出異常,返回錯誤信息
* @param e
* @return
*/
@ExceptionHandler(UnityException.class)
@ResponseBody
public Result customException(UnityException e) {
LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);
return = e.getResult();
}
/**
* 系統產生異常處理
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public Result customException(Exception e) {
LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);
return new Result("服務器異常",null);
}
}
- 優化之前的代碼
public Result demo() {
Demo demo = demoRepository.getDemo();
if (demo == null) {
throw new UnityException(自定義結果);
}
return new Result(CommonCode.SUCCESS, demo);
}
以上提供一種全局異常處理思路,代碼上應該進行再次封裝,比如結果類和拋出異常可以寫成靜態方法、還有result類也需要完善(代碼部分看下就好,只是個Demo)。
當然全局異常處理也有其他的方式,比如springAOP等。