簡體   English   中英

@ControllerAdvice優於@ExceptionHandler或HandlerExceptionResolver處理異常的優點是什么?

[英]What are the advantages of @ControllerAdvice over @ExceptionHandler or HandlerExceptionResolver for handling exceptions?

Spring 3.2引入了@ControllerAdvice注釋來處理Spring MVC應用程序中的異常。 但在此版本之前,Spring使用@ExceptionHandlerHandlerExceptionResolver來處理Spring MVC應用程序中的異常。 那么為什么Spring 3.2引入了@ControllerAdvice注釋來處理異常呢? 我堅信Spring 3.2引入了@ControllerAdvice注釋來解決 @ExceptionHandlerHandlerExceptionResolver 的局限性,或者使異常處理更加強大

任何人都能解釋@ControllerAdvice優於@ExceptionHandlerHandlerExceptionResolver處理異常的優勢嗎?

@ExceptionHandler

@ExceptionHandlerController級別工作 ,它僅對該特定Controller有效,而不是整個應用程序的全局。

HandlerExceptionResolver

這將解決應用程序拋出的任何異常。 它用於將標准Spring異常解析為其相應的HTTP狀態代碼 它無法控制響應的主體,意味着它不會對響應的主體設置任何內容。它會在響應中映射狀態代碼,但正文為空

@ControllerAdvice

@ControllerAdvice用於Spring MVC應用程序中的全局錯誤處理。它還可以完全控制響應的主體和狀態代碼。

@ExceptionHandler是控制器的本地:只有來自此控制器的異常才會路由到他的@ExceptionHandler

@ControllerAdvice是全局的:您可以使用集中的方式來處理異常,綁定等,它適用於所有已定義的控制器。

區別在於:如果我需要配置異常處理代碼,那么我需要在我的項目中使用@ExceptionHandler注釋,它可以在兩個diff.ways中使用:1)使用注釋並在本地處理同一個控制器中的異常在每個控制器類中。 例如:

@RestController
public class WSExposingController{

@GetMapping("/getAllDetails/{/id}")
public UserDetails myMethod(@PathVariable int id){
UserDetails user = UserDetailsService.getUser(id);
return user;
}

//To handle the exceptions which are resulting from this controller, I can declare an exceptionHandler specifically in the same class

@ExceptionHandler(Exception.class)
public ResponseEntity handlerSameControllerExceptions(){
return new ResponseEntity(null,HttpStatus.INTERNAL_SERVER_ERROR);

}

}

2)如果我創建一個擴展ResponseEntityExceptionHandler(SpringBoot類)的新類,並且如果我使用@ControllerAdvice注釋它,則該類變為globalexceptionhandler,這意味着可以在此處處理任何導致任何控制器類的異常。 它可以出現在同一個項目的任何包中。

@RestController
@ControllerAdvice
public class GlobalJavaExceptionHandler extends ResponseEntityExceptionHandler{

    @ExceptionHandler(Exception.class)
    public ResponseEntity handleDiffControllerExceptions(){
        return new ResponseEntity(null,HttpStatus.INTERNAL_SERVER_ERROR);
    }

如果兩者都存在於代碼中,那么本地優先於全局代碼。 理想情況下,第二個選項是更好的選項,因為我們不需要在每個控制器類中添加代碼,並且使用@ControllerAdvice這個類可以是一站式解決方案,用於因控制器到控制器的代碼而產生的所有異常代碼的長度。

@ExceptionHandler可以在本地級別或全局級別使用。 本地級別意味着在控制器本身內使用此注釋來僅處理該控制器內的異常。 該控制器拋出的所有錯誤都將被@ExceptionHandler捕獲。 但這意味着如果在不同的控制器中存在類似的異常,則必須在本地再次在該控制器中重寫相應的代碼。

為了防止每個控制器重復這種類型的異常處理,我們可以在另一個名為@ControllerAdvice的注釋的幫助下在全局級別編寫@ExceptionHanlder。

@ControllerAdvice不是特定於異常處理的,它還用於在全局級別處理屬性,驗證或格式化程序綁定。 異常處理上下文中的@ControllerAdvice只是使用@Exceptionhandler注釋在全局級別進行異常處理的另一種方法。

現在來到HandlerExceptionResolver - 這是一個更低級別的接口。 Spring提供了2個實現:

  • ResponseStatusExceptionResolver:這支持@ResponseStatus注釋的支持
  • ExceptionHandlerExceptionResolver:這支持@ExceptionHandler注釋

示例:因此,當您想要處理異常並選擇異常處理策略時,您需要考慮在通過注釋使用本地或全局異常處理之間進行選擇。 您需要如何提供HTTP狀態代碼,如何將其包裝在@Response實體中,如何重定向到處理程序頁面,通過flash屬性傳送數據或獲取參數等等。或者可以跳過注釋並使用SimpleMappingExceptionResolver並開始將特定異常映射到錯誤處理程序頁面URL

在這里,我們不會考慮在此階段使用HandlerExceptionResolver的較低級別,因為我們正在處理更高級別的實現並基於這些選項構建策略。

使用上面的上下文來回答你的查詢 - @ControllerAdvice沒有引入異常處理,它是一種可以利用@ExceptionHandler全局處理異常的機制。 HandlerExceptionResolver是一個接口,其實現有助於支持@ResponseStatus和@Exceptionhandler注釋。 除非您想要處理與MVC系統相關的異常,否則Spring框架不提供任何適當的異常處理。 因此,如果您需要處理;與錯誤的@Requestmapping等相關的問題,這些問題不會被控制器捕獲,因為它甚至無法在第一個位置到達它,那么HandlerExceptionResolver的實現將是有用的

暫無
暫無

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

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