1、系統(tǒng)對異常的處理使用統(tǒng)一的異常處理流程:
1、自定義異常類型。
2、自定義錯誤代碼及錯誤信息。
3、對于可預(yù)知的異常由程序員在代碼中主動拋出,由SpringMVC統(tǒng)一捕獲
可預(yù)知異常是程序員在代碼中手動拋出本系統(tǒng)定義的特定異常類型,由于是程序員拋出的異常,通常異常信息比較齊全,程序員在拋出時(shí)會指定錯誤代碼及錯誤信息,獲取異常信息也比較方便。
4、對于不可預(yù)知的異常(運(yùn)行時(shí)異常)由SpringMVC統(tǒng)一捕獲Exception類型的異常。
不可預(yù)知異常通常是由于系統(tǒng)出現(xiàn)bug、或一些不要抗拒的錯誤(比如網(wǎng)絡(luò)中斷、服務(wù)器宕機(jī)等),異常類型為
RuntimeException類型(運(yùn)行時(shí)異常)。
5、可預(yù)知的異常及不可預(yù)知的運(yùn)行時(shí)異常最終會采用統(tǒng)一的信息格式(錯誤代碼+錯誤信息)來表示,最終也會隨請求響應(yīng)給客戶端。
異常拋出及處理流程:

1、在controller、service、dao中程序員拋出自定義異常;springMVC框架拋出框架異常類型
2、統(tǒng)一由異常捕獲類捕獲異常,并進(jìn)行處理
3、捕獲到自定義異常則直接取出錯誤代碼及錯誤信息,響應(yīng)給用戶。
4、捕獲到非自定義異常類型首先從Map中找該異常類型是否對應(yīng)具體的錯誤代碼,如果有則取出錯誤代碼和錯誤信息并響應(yīng)給用戶,如果從Map中找不到異常類型所對應(yīng)的錯誤代碼則統(tǒng)一為99999錯誤代碼并響應(yīng)給用戶。
5、將錯誤代碼及錯誤信息以Json格式響應(yīng)給用戶。
1.1可預(yù)知異常處理
1.1.1自定義異常類
public class CustomException extends RuntimeException {
private ResultCode resultCode;
public CustomException(ResultCode resultCode) {
//異常信息為錯誤代碼+異常信息
super("錯誤代碼:"+resultCode.code()+"錯誤信息:"+resultCode.message());
this.resultCode = resultCode;
}
public ResultCode getResultCode(){
return this.resultCode;
}
}
1.1.2異常拋出類
public class ExceptionCast {
//使用此靜態(tài)方法拋出自定義異常
public static void cast(ResultCode resultCode){
throw new CustomException(resultCode);
}
}
1.1.3異常捕獲類
@ControllerAdvice
public class ExceptionCatch {
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);
@ExceptionHandler(CustomException.class)
@ResponseBody
public ResponseResult customException(CustomException e){
LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);
ResultCode resultCode = e.getResultCode();
ResponseResult responseResult = new ResponseResult(resultCode);
return responseResult;
}
}
1.2不可預(yù)知異常處理
1.2.1異常捕獲方法
針對上邊的問題其解決方案是:
1、我們在map中配置HttpMessageNotReadableException和錯誤代碼。
2、在異常捕獲類中對Exception異常進(jìn)行捕獲,并從map中獲取異常類型對應(yīng)的錯誤代碼,如果存在錯誤代碼則返回此錯誤,否則統(tǒng)一返回99999錯誤。
3、在異常捕獲類中配置 HttpMessageNotReadableException 為非法參數(shù)異常。
異常捕獲類代碼如下:
@ControllerAdvice
public class ExceptionCatch {
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);
//定義map,配置異常類型所對應(yīng)的錯誤代碼
private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTIONS;
//定義map的builder對象,去構(gòu)建ImmutableMap
protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableMap.builder();
//捕獲CustomException此類異常
@ExceptionHandler(CustomException.class)
@ResponseBody
public ResponseResult customException(CustomException customException){
//記錄日志
LOGGER.error("catch exception:{}",customException.getMessage());
ResultCode resultCode = customException.getResultCode();
return new ResponseResult(resultCode);
}
//捕獲Exception此類異常
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult exception(Exception exception){
//記錄日志
LOGGER.error("catch exception:{}",exception.getMessage());
if(EXCEPTIONS == null){
EXCEPTIONS = builder.build();//EXCEPTIONS構(gòu)建成功
}
//從EXCEPTIONS中找異常類型所對應(yīng)的錯誤代碼,如果找到了將錯誤代碼響應(yīng)給用戶,如果找不到給用戶響應(yīng)99999異常
ResultCode resultCode = EXCEPTIONS.get(exception.getClass());
if(resultCode !=null){
return new ResponseResult(resultCode);
}else{
//返回99999異常
return new ResponseResult(CommonCode.SERVER_ERROR);
}
}
static {
//定義異常類型所對應(yīng)的錯誤代碼
builder.put(HttpMessageNotReadableException.class,CommonCode.INVALID_PARAM);
}
}