自定義異常及異常全域性處理
一、Java異常分類
java中異常均繼承自Throwable,其有兩個重要的直接子類error與exception
- Error:
大部分是由虛擬機器報出來的錯誤,是程式無法處理的錯誤,如 OutOfMemoryError,當JVM需要更多記憶體空間而得不到滿足時,就會報出OutOfMemoryError(記憶體溢位)
- Exception
-
非RuntimeException(編譯期異常)
在程式碼書寫時,編譯器給你檢查提示你要進行try catch或throws處理。如IOException,SQLException等
-
RuntimeException(執行時異常)
編譯器不會幫你自動檢查,當你執行程式時,虛擬機器才會給你爆出錯誤讓你去處理,這個往往是我們編碼邏輯或不規範導致的。
二、案例分析
1、自定義的業務異常類:BusinessException
@Getter public class BusinessException extends Exception { private int code; public BusinessException(int code,String message) { super(message); this.code = code; } }
2、在service層中丟擲業務性異常:
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper;
@Override
public void testException() throws Exception {
throw new BusinessException(10001,"引數異常");
}
}
3、在controller層中繼續向上拋異常
@RestController public class StudentController { @Autowired private StudentService studentService; @RequestMapping("/testException") public void testException() throws Exception { studentService.testException(); } }
4、異常統一攔截
返回的異常,都需要經過統一的處理,同樣spring也提供了介面對異常的返回
全域性異常處理類:GlobalExceptionHandler
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
@ResponseBody
public BaseResponse jsonErrorHandler(HttpServletRequest request, Exception e) throws Exception{
BaseResponse response = new BaseResponse();
if( e instanceof BusinessException ){
response.setCode(((BusinessException)e).getCode());
response.setMessage(e.getMessage());
} else {
log.error(e.getMessage(),e);
response.setCode(ResponseEnum.SYSTEM_ERROR.getCode());
response.setMessage(ResponseEnum.SYSTEM_ERROR.getMessage());
}
return response;
}
}
@ControllerAdvice:
是一個@Component,用於定義@ExceptionHandler,@InitBinder和@ModelAttribute方法,適用於所有使用@RequestMapping方法。
BaseResponse 基礎響應實體類
import lombok.Data;
@Data
public class BaseResponse {
private Integer code;
private String message;
}
ResponseEnum
@Getter
@AllArgsConstructor
public enum ResponseEnum {
SYSTEM_ERROR(9999,"系統異常");
private Integer code;
private String message;
}
三、測試
訪問: http://localhost:8080/testException
大功告成,和預期的結果一樣
四、總結
處理邏輯:
自定義異常類 --> 在service層向上丟擲自定義異常類 --> 在controller層把自定義異常類繼續向上拋 --> 用自定義的全域性異常處理類進行統一攔截捕獲並處理
自定義異常的好處:
1.異常資訊明確,能夠快速定位問題
2.統一程式碼業務性問題處理規範
3.方便錯誤資料的封裝,後臺資料機構的統一(統一異常攔截體現)