spring-boot-route(四)全局異常處理

在開發中,咱們常常會使用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(三)實現多文件上傳緩存

spring-boot-route(四)全局異常處理微信

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(十一)數據庫配置信息加密

spring-boot-route(十二)整合redis作爲緩存

spring-boot-route(十三)整合RabbitMQ

spring-boot-route(十四)整合Kafka

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(二十二)實現郵件發送功能

spring-boot-route(二十三)開發微信公衆號

這個系列的文章都是工做中頻繁用到的知識,學完這個系列,應付平常開發綽綽有餘。若是還想了解其餘內容,掃面下方二維碼告訴我,我會進一步完善這個系列的文章!

相關文章
相關標籤/搜索