在開發中,咱們常常會使用try/catch塊
來捕獲異常進行處理,若是有些代碼中忘記捕獲異常或者不可見的一些異常出現,就會響應給前端一些不友好的提示,這時候咱們能夠使用全局異常處理。這樣就不用在代碼中寫那些煩人的try/catch塊了
,代碼的可讀性也會提升。前端
SpringBoot提供的的註解@ControllerAdvice
表示開啓全局異常捕獲,在自定義的異常方法上使用ExceptionHandler
來進行統一處理。java
下面一塊兒看看如何優雅的處理全局異常!git
一 定義響應狀態碼及信息的枚舉類
@Getter public enum CodeEnum { SUCCESS(0,"請求成功"), ERROR(500,"未知異常"), ERROR_EMPTY_RESULT(1001,"查詢結果爲空"), ERROR_INCOMPLETE_RESULT(1002,"請求參數不全"); private int code; private String message; CodeEnum(int code,String message){ this.code = code; this.message = message; } }
二 定義響應數據的實體類
@Slf4j @Data public class R<T> implements Serializable { private static final long serialVersionUID = 572235155491705152L; /** * 響應的狀態碼 */ private int code; /*** * 響應的信息 */ private String message; /** * 響應數據 */ private T data; /** * 放入響應碼並返回 * @param code * @param msg * @return */ public R fillCode(int code,String msg){ this.code = code; this.message = msg; return this; } /** * 放入響應碼並返回 * @param codeEnum * @return */ public R fillCode(CodeEnum codeEnum){ this.code = codeEnum.getCode(); this.message = codeEnum.getMessage(); return this; } /** * 放入數據並響應成功狀態 * @param data * @return */ public R fillData(T data){ this.code = CodeEnum.SUCCESS.getCode(); this.message = CodeEnum.SUCCESS.getMessage(); this.data = data; return this; } }
三 自定義兩個異常
根據業務需求自定義異常,在本文中我定義了兩個異常,分別用做響應結果爲空時處理和請求參數錯誤時處理。github
@Data public class EmptyResutlException extends RuntimeException { private static final long serialVersionUID = -8839210969758687047L; private int code; private String message; public EmptyResutlException(CodeEnum codeEnum){ this.code = codeEnum.getCode(); this.message = codeEnum.getMessage(); } }
@Data public class RequestParamException extends RuntimeException { private static final long serialVersionUID = 4748844811214637041L; private int code; private String message; public RequestParamException(CodeEnum codeEnum){ this.code = codeEnum.getCode(); this.message = codeEnum.getMessage(); } }
四 定義全局異常處理類
因爲這裏我想要響應的結果爲實體類對象,所以我直接用@RestControllerAdvice
來代替了@ControllerAdvice
,這兩個註解的差異跟@Controller
和@RestController
同樣,rest的響應體爲json格式的數據。redis
@RestControllerAdvice @Slf4j public class GlobalExceptionHandler { /** * 查詢結果爲空時處理 * @param e * @return */ @ExceptionHandler(EmptyResutlException.class) public R emptyResultExceptionHandler(EmptyResutlException e){ log.error("查詢結果爲空:{}",e.getMessage()); R result = new R(); result.fillCode(e.getCode(),e.getMessage()); return result; } /** * 請求參數錯誤時處理 * @param e * @return */ @ExceptionHandler(RequestParamException.class) public R requestParamExceptionHandler(RequestParamException e){ log.error("請求參數不合法:{}",e.getMessage()); R result = new R(); result.fillCode(e.getCode(),e.getMessage()); return result; } /** * 處理其餘異常 * @param e * @return */ @ExceptionHandler(Exception.class) public R exceptionHandler(Exception e){ log.error("未知異常:{}",e.getMessage()); R result = new R(); result.fillCode(CodeEnum.ERROR); return result; } }
五 自定義接口測試異常
@RestController public class TestController { @GetMapping("getString") public R getString(String name){ if(StringUtils.isEmpty(name)){ throw new RequestParamException(1002,"請求參數name爲空"); }else if ("Java旅途".equals(name)) { // 這裏沒有查詢操做,當請求參數是Java旅途的時候,模擬成查詢結果爲空 throw new EmptyResutlException(1001,"查詢結果爲空"); } // 這裏模擬一下除自定義異常外的其餘兩種異常 int i = 0; i = 5/i; return new R().fillData(name); } }
在實際開發中能夠自定義響應狀態碼的枚舉類和自定義異常以知足需求。spring
本文示例代碼已上傳至github,點個star
支持一下!
Spring Boot系列教程目錄
spring-boot-route(一)Controller接收參數的幾種方式數據庫
spring-boot-route(二)讀取配置文件的幾種方式json
spring-boot-route(五)整合Swagger生成接口文檔
spring-boot-route(六)整合JApiDocs生成接口文檔
spring-boot-route(七)整合jdbcTemplate操做數據庫
spring-boot-route(八)整合mybatis操做數據庫
spring-boot-route(九)整合JPA操做數據庫
spring-boot-route(十一)數據庫配置信息加密
spring-boot-route(十二)整合redis作爲緩存
spring-boot-route(十三)整合RabbitMQ
spring-boot-route(十五)整合RocketMQ
spring-boot-route(十六)使用logback生產日誌文件
spring-boot-route(十七)使用aop記錄操做日誌
spring-boot-route(十八)spring-boot-adtuator監控應用
spring-boot-route(十九)spring-boot-admin監控服務
spring-boot-route(二十)Spring Task實現簡單定時任務
spring-boot-route(二十一)quartz實現動態定時任務
spring-boot-route(二十二)實現郵件發送功能
這個系列的文章都是工做中頻繁用到的知識,學完這個系列,應付平常開發綽綽有餘。若是還想了解其餘內容,掃面下方二維碼告訴我,我會進一步完善這個系列的文章!