異常處理在項目中還是比較重要的,springboot 中的異常有些類似於springmvc,熟悉springmvc的朋友就不會那麼陌生了。爲什麼我們在項目中需要做全局異常處理暱,實際是可以在每一個contoller中的每一個方法中加入try catch,實現對異常的處理,但是這樣寫就會變焦麻煩,代碼也會比較冗餘,所以使用全局異常處理,在service中直接拋出異常就可以了,非常的簡單。
1.優缺點
- 優點:將 Controller 層的異常和數據校驗的異常進行統一處理,減少模板代碼,減少編碼量,提升擴展性和可維護性。
- 缺點:只能處理 Controller 層未捕獲(往外拋)的異常,對於 Interceptor(攔截器)層的異常,Spring 框架層的異常,就無能爲力了。
- 對於 Interceptor(攔截器)或者spring框架等其他的異常try catch 返回自己定義的異常類。
2.首先主要講兩個註解
@ControllerAdvice 和 @ExceptionHandler
2.1 @ControllerAdvice 註解定義全局異常處理類
@ControllerAdvice
public class GlobalExceptionHandler {
}
請確保此 GlobalExceptionHandler 類能被掃描到並裝載進 Spring 容器中。
2.2 @ExceptionHandler 註解聲明異常處理方法
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
String handleException(){
return "Exception Deal!";
}
}
方法 handleException() 就會處理所有 Controller 層拋出的 Exception 及其子類的異常,這是最基本的用法了。
如果 @ExceptionHandler 註解中未聲明要處理的異常類型,則默認爲參數列表中的異常類型。所以上面的寫法,還可以寫成這樣:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler()
@ResponseBody
String handleException(Exception e){
return "Exception Deal! " + e.getMessage();
}
}
3.附上代碼
3.1全局異常處理
此類中可以根據不同的異常做不同的處理
package com.example.exception; import com.example.entity.ResultModel; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; /** * 全局異常捕獲 */ @ControllerAdvice public class GlobalDefultExceptionHandler { //聲明要捕獲的異常 @ExceptionHandler(value = BizException.class) @ResponseBody public ResultModel<String> defultExcepitonHandler(HttpServletRequest request, BizException e) { ResultModel<String> resultModel = new ResultModel<String>(); if(e instanceof BizException) { BizException bizException = (BizException)e; resultModel.setMessage(bizException.getMessage()); resultModel.setCode(bizException.getCode()); return resultModel; } resultModel.setCode(e.getCode()); resultModel.setMessage(e.getMessage()); return resultModel; } }
3.2自定義的異常類
package com.example.exception; /** * 異常描述 */ public class BizException extends RuntimeException{ /** * 具體異常碼 */ protected int code; /** * 異常信息 */ protected String msg; public BizException(int code, String msgFormat, Object... args) { super(String.format(msgFormat, args)); this.code = code; this.msg = String.format(msgFormat, args); } public BizException(int code, String msg) { super(String.format(msg)); this.code = code; this.msg = msg; } public BizException(int code, java.lang.Exception ex) { super(ex.getMessage(), ex.getCause()); this.code = code; this.msg = ex.getMessage(); } public BizException() { super(); } public String getMsg() { return msg; } public int getCode() { return code; } /** * 實例化異常 * * @param msgFormat * @param args * @return */ public BizException newInstance(String msgFormat, Object... args) { return new BizException(this.code, msgFormat, args); } public BizException(String message, Throwable cause) { super(message, cause); } public BizException(Throwable cause) { super(cause); } public BizException(String message) { super(message); } @Override public String toString(){ return String.format("code:%s,msg:%s,RuntimeException's info:{%s}", this.code, this.msg, super.toString().equals("") ? "無" : super.toString()); } }