第六篇:SpringBoot統一異常處理
阿新 • • 發佈:2018-12-12
一、什麼是異常處理
異常(Exception)是程式在執行時可能出現的會導致程式執行終止的錯誤。這種錯誤是不能通過編譯系統檢查出來的,如果不進行異常處理,程式將中斷無法提供服務。
二、如何使用Spring Boot異常處理
案例:
獲取某個女生的年齡並判斷小於10,返回應該還在上小學大於10且小於16,返回可能在上初中!
1.建立實體Girl類
@Entity @Data /** * fasterxml.jackson 將物件轉換為json報錯處理 */ @JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" }) public class Girl { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @NotBlank(message = "這個欄位必傳") private String cupSize; @NotNull(message = "金額必傳") private Double money; @Min(value = 18, message = "年齡必須大於18歲") private Integer age; }
2.建立ResponseVO類用於響應前端請求資料
@Data
/* 1.定義一個封裝類,用於封裝資料返回給前端*/
public class ResponseVO<T> {
/*錯誤碼*/
private Integer code;
/*提示資訊*/
private String msg;
/* 使用泛型封裝資料*/
private T data;
}
3.建立ResultEnum列舉用來管理異常資訊
** * 使用列舉類關聯錯誤碼 */ @Getter public enum ResultEnum { UNKNOW_ERROR(-1, "未知錯誤"), SUCCESS(0, "成功"), PRIMARY_SCHOOL(100, "你可能在上小學"), MIDDLE_SCHOOL(101, "你可能在上初中"),; private Integer code; private String msg; ResultEnum(Integer code, String msg) { this.code = code; this.msg = msg; } }
4.建立ResultUtil工具類
作用:封裝資料響應前端請求
/*編寫一個工具類*/ public class ResultUtil { /* 1.返回成功顯示的資料*/ public static ResponseVO success(Object object) { ResponseVO result = new ResponseVO(); result.setCode(0); result.setMsg("成功"); result.setData(object); return result; } public static ResponseVO success() { return success(null); } /* 1.返失敗攜帶的資料*/ public static ResponseVO error(Integer code, String msg) { ResponseVO result = new ResponseVO(); result.setCode(code); result.setMsg(msg); return result; } }
5.建立GirlController介面接收前端請求
/**
* 通過id查詢一個物件的年齡,並判斷大小,返回不同結果
* @param id
* @return
* @throws Exception
*/
@GetMapping(value = "/girls/getAge/{id}")
public ResponseVO getGirlById(@PathVariable("id") Integer id) throws Exception{
return ResultUtil.success(girlService.getAge(id));
}
情況一:當id=1從資料庫查詢出年齡為6歲小於10,因此丟擲異常!剛好被ExceptionHandle接收並處理。
結果為:
情況二: 當id=3從資料庫查詢出年齡為20歲大於16,因此無異常發生,正常返回資料給前端。
結果為:
6.建立GirlService類,處理業務有異常往外拋!
@Service
public class GirlService {
@Autowired
private GirlRepository girlRepository;
public Girl getAge(Integer id)throws Exception{
Girl girl=girlRepository.getOne(id);
Integer age=girl.getAge();
if (age<10){
//返回“你可能在上小學” code=100
throw new GirlException(ResultEnum.PRIMARY_SCHOOL);
}else if(age>10 && age<16){
//返回“你可能在上初中” code=101
throw new GirlException(ResultEnum.MIDDLE_SCHOOL);
}
return girl;
}
}
7.建立異常類GirlException封裝異常資訊
public class GirlException extends RuntimeException {
private Integer code;
public GirlException(ResultEnum resultEnum) {
//父類的構造方法本身會傳message進去
super(resultEnum.getMsg());
this.code = resultEnum.getCode();
}
public Integer getCode() {
return code;
}
}
8.建立統一異常處理ExceptionHandle類,用於處理service發生的異常!
如果service層業務出現異常,直接跳到統一異常處理類中處理異常!
/**
* @ControllerAdvice + @ExceptionHandler 組合進行的 Controller 層上丟擲
* 異常全域性統一處理
*/
@ControllerAdvice
public class ExceptionHandle {
//記錄系統異常
private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
/**
* [email protected](GirlException.class) 聲明瞭對 GirlException業務異常的處理,
* 並獲取該業務異常中的錯誤提示,構造後返回給客戶端。
*
* [email protected](Exception.class) 聲明瞭對 Exception 異常的處理,起到兜底作用,
* 不管 Controller 層執行的程式碼出現了什麼未能考慮到的異常,都返回統一的錯誤提示給客戶端。
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResponseVO handle(Exception e) {
/* 判斷異常物件*/
if (e instanceof GirlException) {
GirlException girlException = (GirlException) e;
return ResultUtil.error(girlException.getCode(), girlException.getMessage());
} else {
logger.error("【系統異常】 {}",e);
return ResultUtil.error(-1, "未知錯誤");
}
}
}