統一異常處理相關注解介紹
@ControllerAdvice
聲明在類上用於指定該類為控制增強器類,如果想聲明返回的結果為 RESTFull 風格的數據,需要在聲明 @ExceptionHandler 注解的方法上同時加 上 @ResponseBody
@RestControllerAdvice
聲明在類上用於指定該類為控制增強器類。並聲明返回的結果為 RESTFull 風格的數據,無需在聲明 @ExceptionHandler 注解的方法上加
@ResponseBody
@ExceptionHandler
聲明在方法上用於指定需要統一攔截的異常。例如:@ExceptionHandler(value = Exception.class)
實戰操作
定義消息類:
定義 RESTFull 返回 JSON 數據的消息類,其中包含成員變量如下:
- code:錯誤碼,0表示沒有異常信息。
- message:異常提示信息。
- date:無異常是返回具體內容信息。
public class ReturnMessage<T> {
private Integer code;//錯誤碼
private String message;//提示信息
private T date;//返回具體內容
public ReturnMessage(Integer code, String message, T date) {
super();
this.code = code;
this.message = message;
this.date = date;
}
//省略get and set方法
}
** 消息類處理工具類:**
主要是用來處理成功或失敗消息處理,該工具類主要包含是3個方法 :
- 成功處理含實體數據
- 成功處理 沒有實體數據
- 失敗處理
具體代碼如下:
public class ReturnMessageUtil {
/**
* 無異常 請求成功並有具體內容返回
* @param object
* @return
*/
public static ReturnMessage<Object> sucess(Object object) {
ReturnMessage<Object> message = new ReturnMessage<Object>(0,"sucess",object);
return message;
}
/**
* 無異常 請求成功並無具體內容返回
* @return
*/
public static ReturnMessage<Object> sucess() {
ReturnMessage<Object> message = new ReturnMessage<Object>(0,"sucess",null);
return message;
}
/**
* 有自定義錯誤異常信息
* @param code
* @param msg
* @return
*/
public static ReturnMessage<Object> error(Integer code,String msg) {
ReturnMessage<Object> message = new ReturnMessage<Object>(code,msg,null);
return message;
}
}
自定義異常類:
我們通過自定義系統異常類來完成校驗相關的操作,自定義系統異常類通過繼承 RuntimeException ,然后聲明名稱為 code 的成員變量來表示不同類型異常。
主要是用於異常攔截后獲取自定義異常的 code ,並將code 設置到消息類中。
public class SbException extends RuntimeException{
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public SbException(Integer code,String message) {
super(message);
this.code = code;
}
}
定義統一異常攔截類:
通過聲明 @RestControllerAdvice 表示該類為 RESTFul 風格的異常處理控制增強器類,在 handle 方法聲明 @ExceptionHandler 並在該注解中指定要攔截的異常類。具體代碼如下:
@RestControllerAdvice
public class ExceptionHandle {
private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
@ExceptionHandler(value = Exception.class)
public ReturnMessage<Object> handle(Exception exception) {
if(exception instanceof SbException) {
SbException sbexception = (SbException)exception;
return ReturnMessageUtil.error(sbexception.getCode(), sbexception.getMessage());
}else {
logger.error("系統異常 {}",exception);
return ReturnMessageUtil.error(-1, "未知異常"+exception.getMessage());
}
}
}
測試
分別測試自定義異常和系統異常,通過 /error/custome 測試自定義異常,通過 /error/unknown 測試未知的系統異常。具體代碼如下:
@RestController
@RequestMapping("/error")
public class DemoException {
@GetMapping(value = "custome")
public void customException() {
SbException sbe = new SbException(100, "這個是自定義異常!");
throw sbe;
}
@GetMapping(value = "unknown")
public void unknownException() {
int i = 0;
int b = 1/i;
}
}
測試結果: