這篇教程主要專一於如何優雅的處理WEB中的異常。雖然咱們能夠手動的設置ResponseStatus
,可是還有更加優雅的方式將這部分邏輯隔離開來。Spring提供了整個應用層面的異常處理的抽象,而且只是要求您添加一些註釋 - 它會處理其餘全部內容。下面是一些代碼的示例面試
下面的代碼中, DogController
將返回一個ResponseEntity
實例,該實例中包含返回的數據和HttpStatus
屬性spring
List<Dog>
數據做爲響應體,以及200做爲狀態碼DogsNotFoundException
,它返回空的響應體和404狀態碼DogServiceException
, 它返回500狀態碼和空的響應體@RestController @RequestMapping("/dogs") public class DogsController { @Autowired private final DogsService service; @GetMapping public ResponseEntity<List<Dog>> getDogs() { List<Dog> dogs; try { dogs = service.getDogs(); } catch (DogsServiceException ex) { return new ResponseEntity<>(null, null, HttpStatus.INTERNAL_SERVER_ERROR); } catch (DogsNotFoundException ex) { return new ResponseEntity<>(null, null, HttpStatus.NOT_FOUND); } return new ResponseEntity<>(dogs, HttpStatus.OK); } }
這種處理異常的方式最大的問題就在於代碼的重複。catch部分的代碼在不少其它地方也會使用到(好比刪除,更新等操做)微信
Spring提供了一種更好的解決方法,也就是Controller Advice。它將處理異常的代碼在應用層面上集中管理。app
如今咱們的的DogsController的代碼更加簡單清晰了:spa
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; import static org.springframework.http.HttpStatus.NOT_FOUND; @ControllerAdvice public class DogsServiceErrorAdvice { @ExceptionHandler({RuntimeException.class}) public ResponseEntity<String> handleRunTimeException(RuntimeException e) { return error(INTERNAL_SERVER_ERROR, e); } @ExceptionHandler({DogsNotFoundException.class}) public ResponseEntity<String> handleNotFoundException(DogsNotFoundException e) { return error(NOT_FOUND, e); } @ExceptionHandler({DogsServiceException.class}) public ResponseEntity<String> handleDogsServiceException(DogsServiceException e){ return error(INTERNAL_SERVER_ERROR, e); } private ResponseEntity<String> error(HttpStatus status, Exception e) { log.error("Exception : ", e); return ResponseEntity.status(status).body(e.getMessage()); } }
handleRunTimeException
:這個方法會處理全部的RuntimeException
並返回INTERNAL_SERVER_ERROR
狀態碼handleNotFoundException
: 這個方法會處理DogsNotFoundException
並返回NOT_FOUND
狀態碼。handleDogsServiceException
: 這個方法會處理DogServiceException
並返回INTERNAL_SERVER_ERROR
狀態碼這種實現的關鍵就在於在代碼中捕獲需檢查異常並將其做爲RuntimeException
拋出。code
還能夠用@ResponseStatus
將異常映射成狀態碼教程
@ControllerAdvice public class DogsServiceErrorAdvice { @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler({DogsNotFoundException.class}) public void handle(DogsNotFoundException e) {} @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler({DogsServiceException.class, SQLException.class, NullPointerException.class}) public void handle() {} @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler({DogsServiceValidationException.class}) public void handle(DogsServiceValidationException e) {} }
@ResponseStatus(HttpStatus.NOT_FOUND) public class DogsNotFoundException extends RuntimeException { public DogsNotFoundException(String message) { super(message); } }
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注個人微信公衆號!將會不按期的發放福利哦~ip