優雅規範的拋出異常

可能會拋出異常的接口

方式1:直接返回給用戶一個狀態碼,而需要返回的對象返回null,這樣是不太友好的,或者是在給用戶返回一個錯誤信息字符串,這樣有與該接口的返回值衝突。
方式2:使用throw new RuntimeException("錯誤信息");這樣是可以的,但是這樣直接將異常拋出,用戶看見的是一個狀態碼爲500的錯誤,這是屬於服務端錯誤,而這實際上是由於客戶端導致的錯誤,與我們的程序沒有關係的,也不妥當。
方式3:拋出自定義異常

@RestController
@RequestMapping("item")
public class ItemController {
    @Autowired
    private ItemService itemService;
    @PostMapping
    /*
    ResponseEntity類似於ResponseBody:
    ResponseEntity(把java對象序列化放到響應實體中,實體包含狀態碼、響應體等,是一個較完整的http響應)
    ResponseBody(把java對象序列化放到響應體中,默認是json形式)
     */
    public ResponseEntity<Item> saveItem(Item item) {
        //校驗價格
        if(item.getPrice()==null){
            //return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);//直接返回null,不太友好,改成字符串提示信息“價格不能爲空”,又與返回值的泛型不匹配
            //throw new RuntimeException("價格不能爲空!!");//但是這樣將異常拋出,是一個服務器內部異常500,好像是服務器出問題了,但是實際上這個異常是客戶端導致的異常。
            throw new LyException(ExceptionEnum.PRICE_CANNOT_BE_NULL);
        }

        item = itemService.saveItem(item);
        return ResponseEntity.status(HttpStatus.CREATED).body(item);
    }
}

common組件的描述如圖。
在這裏插入圖片描述

異常攔截器

@ControllerAdvice:“控制器通知”,所有的controller接口執行前,默認都會執行這個通知類。
@ExceptionHandler(LyException.class):用來指明異常的處理類型,即如果這裏指定爲 LyException自定義的異常,則出現該異常就會進到這個方法中來。
返回值:是泛型爲自定義的異常結果的一個http響應實體。 ResponseEntity類似於ResponseBody,ResponseEntity把java對象序列化放到響應實體中,實體包含狀態碼、響應體等,是一個較完整的http響應,而ResponseBody是把java對象序列化放到響應體中,默認是json形式。

/**
 * 默認會自動攔截所有的controller的通知類
 */
@ControllerAdvice
public class CoommonExceptionHandler {

    @ExceptionHandler(LyException.class)//攔截不同的異常,對其進行處理
    public ResponseEntity<ExceptionResult> handleException(LyException e){
        ExceptionEnum em = e.getExceptionEnum();
        return ResponseEntity.status(em.getCode()).body(new ExceptionResult(em));
    }
}

異常返回結果類

使用枚舉定義常量異常信息

@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum  ExceptionEnum {
    //private static final ExceptionEnum ff=new ExceptionEnum(400,"價格不能爲空");簡化爲下面
    //還可添加更多異常常量
    PRICE_CANNOT_BE_NULL(400,"價格不能爲空");
    ;

    private int code;//狀態碼
    private String msg;//信息
}

異常結果類,在構造方法中傳入了異常枚舉信息,給當前結果複製。

@Data
public class ExceptionResult {
	/*
	這裏還可以根據需求,添加許多信息
	*/
    private int status;//狀態碼
    private String message;//異常信息
    private Long timestamp;//時間戳

    public ExceptionResult(ExceptionEnum em) {
        this.status = em.getCode();
        this.message = em.getMsg();
        this.timestamp = System.currentTimeMillis();
    }
}

根據應用、模塊自定義異常類。

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class LyException extends RuntimeException{
    private ExceptionEnum exceptionEnum;
}

處理過程

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章