簡體   English   中英

Spring中的自定義@ControllerAdvice用於異常處理

[英]Custom @ControllerAdvice in Spring for exception handling

我試圖將我的其余控制器中的異常映射到具有主體的響應,並將其集中放置。

我已經試過了:

@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestErrorResponseExceptionHandler extends ResponseEntityExceptionHandler {
    @Override
    protected ResponseEntity<Object> handleExceptionInternal(
        Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
        super.handleExceptionInternal(ex, body, headers, status, request);

        return ResponseEntity.status(status).body(Error.from(status));
    }
} 

問題是處理程序永遠不會觸發。

如果我在我的rest控制器中使用@ExceptionHandler定義一個自定義方法,或者擴展具有@ExceptionHandler東西,那么所有方法都可以正常工作,但這會帶來一些不良設計。

據我了解,Spring首先會嘗試在控制器中查找異常處理方法,然后將檢查注冊的處理程序。

我正在嘗試通過WebMvcTest驗證行為,並且得到的響應不是我期望的Error對象。

有什么我想念的嗎?

ControllerAdvice是必須由Spring注冊的配置。 您必須將類移到config包中,也可以通過注釋進行注冊。

就我而言,我使用的controllerAdvice像這樣:

@ControllerAdvice
public class GlobalControllerExceptionHandler {

    @ExceptionHandler(MyException.class) 
    public ResponseEntity<String> reponseMyException(Exception e) {
        return ResponseEntity.status(HttpStatus.FORBIDDEN).body("my message");
    }
}

Spring Framework提供了以下方法來幫助我們實現可靠的異常處理。

  1. 基於控制器 –我們可以在控制器類中定義異常處理程序方法。 我們所需要做的就是用@ExceptionHandler注釋對這些方法進行注釋。 該注釋將Exception類作為參數。 因此,如果我們為Exception類定義了其中一種,那么請求處理程序方法拋出的所有異常都將得到處理。 這些異常處理程序方法與其他請求處理程序方法一樣,我們可以構建錯誤響應並使用不同的錯誤頁面進行響應。 我們還可以發送JSON錯誤響應,我們將在示例后面查看。 如果定義了多個異常處理程序方法,則使用最接近Exception類的處理程序方法。 例如,如果我們為IOException和Exception定義了兩個處理程序方法,並且我們的請求處理程序方法拋出IOException,則將執行IOException的處理程序方法。

  2. 全局異常處理程序 –異常處理是一個跨領域的問題,應該對我們應用程序中的所有切入點進行處理。 我們已經研究過Spring AOP,這就是Spring提供@ControllerAdvice批注的原因,我們可以將其與任何類一起使用來定義全局異常處理程序。 Global Controller Advice中的處理程序方法與基於Controller的異常處理程序方法相同,並且在controller類無法處理異常時使用。

  3. HandlerExceptionResolver –對於一般異常,大多數時候我們提供靜態頁面。 Spring框架提供了HandlerExceptionResolver接口,我們可以實現該接口來創建全局異常處理程序。 這種定義全局異常處理程序的其他方法背后的原因是,Spring框架還提供了默認實現類,我們可以在我們的Spring bean配置文件中定義這些默認實現類以獲得Spring框架異常處理的好處。 SimpleMappingExceptionResolver是默認的實現類,它允許我們配置exceptionMappings,在其中可以指定用於特定異常的資源。 我們還可以覆蓋它,以使用應用程序特定的更改(例如,記錄異常消息)來創建自己的全局處理程序。

確保兩件事,您的代碼將正常工作。

  1. 您的@ControllerAdvice類在組件掃描路徑中可用。
  2. 確保@ControllerAdvice的方法具有類似以下的結構-
    @ExceptionHandler(value = { RequestProcessingException.class })
    public @ResponseBody ResponseEntity<ErrorMessageBO> hotelConfigServiceExceptionHandler(HttpServletRequest request, RequestProcessingException e) {
       logger.error("Exception with tracking Id: {}, dev message: {} and Message:", RequestContextKeeper.getContext().getRequestId(), e.getDeveloperMessage(),e);
       return new ResponseEntity<ErrorMessageBO>(new ErrorMessageBO(e.getErrorCode(), e.getMessage(),RequestContextKeeper.getContext().getRequestId(),e.getDeveloperMessage()), HttpStatus.OK);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM