爲了不代碼冗餘以及異常信息不明確,咱們通常都是使用自定義異常,而後在統一異常處理類中捕獲並處理,處理完後封裝到統一的響應中返回給客戶端數據庫
自定義異常類型安全
自定義錯誤代碼以及錯誤信息函數
可預知異常在代碼中手動拋出,由SpringMVC捕獲post
不可知異常由SpringMVC統一捕獲Exception處理測試
不管可預知仍是不可知異常,最後都採用統一的信息格式響應給客戶端ui
ResultCode:封裝了三個信息,分別是: 是否成功、響應碼、提示信息google
提供get(),至於set()是經過構造方法傳入並賦值spa
這個就是咱們再代碼中想拋出預知異常所使用的類線程
經過靜態方法cast(),傳入異常的具體信息,而後拋出一個自定義異常,將異常信息做爲參數帶入3d
@ControllerAdvice:統一異常處理
@RestControllerAdvice:若是統一響應的Json數據,能夠使用這個
@ExceptionHandle:有一個方法指定捕獲的異常類型,捕獲後交由下方函數處理
if ( ){ //對什麼進行判斷,並拋出自定義異常 ExceptionCast.cast(CmsCode.CMS_ADDPAGE_EXISTSNAME); }
至於:CmsCode.CMS_ADDPAGE_EXISTSNAME
是一個枚舉類,固定了: 是否成功--響應碼--提示信息
簡單說說:所謂的不可預知異常,通常指的是請求數據轉換異常,數據庫鏈接異常...等
由於太長,我就貼代碼了:
//使用ImmutableMap存放異常類型和錯誤代碼的映射,這個對象線程安全,一旦建立不可變 private static ImmutableMap<Class<? extends Throwable>,ResultCode> EXCEPTION_MAP; //使用builder來構建一個異常類型和錯誤代碼的異常 protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableMap.builder(); @ExceptionHandler(Exception.class) @ResponseBody public ResponseResult Exception(Exception e){ LOGGER.error("catch Exception:",e.getMessage(),e); //若是集合爲空 if (EXCEPTION_MAP == null) //構建集合 EXCEPTION_MAP = builder.build(); //嘗試在集合中或許捕獲的異常信息 final ResultCode resultCode = EXCEPTION_MAP.get(e.getClass()); //定義統一的響應體 final ResponseResult response; //若是集合中有這個異常相關的信息 if (resultCode != null){ //將異常信息封裝到統一響應體中返回,咱們只有一個數據,那就是: false---10003---非法參數 response = new ResponseResult(resultCode); }else{ //CommonCode.SERVER_ERROR:false - 99999 - 系統繁忙,請稍後再試 response = new ResponseResult(CommonCode.SERVER_ERROR); } return response; }
//咱們手動加入一部風數據到map中,待會兒用於測試 static{ //接口要就post提交時,咱們不給Json數據直接提交,以add爲列,觸發這個異常而後被捕獲
//CommonCode.INVALID_PARAM :false --- 10003-----非法參數
builder.put(HttpMessageNotReadableException.class, CommonCode.INVALID_PARAM); }
咱們定義了一個Map() :
key是一個異常,由於泛型規定了他必須繼承Throwable
Value是觸發該異常後的響應信息(是否操做成功----響應碼----提示信息)
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency>
當咱們攔截到未預知的異常時,首先去這個集合中查詢室友有相關的信息
若是有,就直接封裝對應的Value到統一響應體中響應
若是在集合中沒有查詢到對應的異常信息,統一返回:"系統繁忙"這個響應體
完!