可能會拋出異常的接口
方式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;
}
處理過程