1. 程式人生 > >第六篇:SpringBoot統一異常處理

第六篇:SpringBoot統一異常處理

一、什麼是異常處理

異常(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, "未知錯誤");
        }
    }
}