web-dev-qa-db-ja.com

例外を処理する場合の@ExceptionHandlerまたはHandlerExceptionResolverに対する@ControllerAdviceの利点は何ですか?

Spring 3.2では、Spring MVCアプリケーションで例外を処理するための@ControllerAdviceアノテーションが導入されました。しかし、このバージョン以前は、Springは、Spring MVCアプリケーションで例外を処理するために@ExceptionHandlerまたはHandlerExceptionResolverを備えていました。では、なぜSpring 3.2は、例外を処理するために@ControllerAdviceアノテーションを導入したのですか? Spring 3.2@ControllerAdviceアノテーションを導入して、@ExceptionHandlerまたはHandlerExceptionResolverまたは例外をより強力に処理する

例外を処理する場合の@ControllerAdviceまたはHandlerExceptionResolverに対する@ExceptionHandlerの利点を説明できる人はいますか?

21
Rajorshi Roy

@ExceptionHandler

@ExceptionHandlerコントローラレベルで機能し、その特定のコントローラに対してのみアクティブであり、アプリケーション全体に対してグローバルではありません。

HandlerExceptionResolver

これにより、アプリケーションによってスローされた例外が解決されます。これは、標準のSpring例外を対応するHTTPステータスコードに解決するために使用されます。これは、応答の本文を制御できない、つまり応答の本文には何も設定しないです。これは、応答のステータスコードをマップしますが、本体はnullです)

@ControllerAdvice

@ControllerAdvice Spring MVCアプリケーションのグローバルエラー処理に使用されます。また、応答の本文とステータスコードを完全に制御できます。

31
Bacteria

@ExceptionHandlerはコントローラーに対してローカルです。このコントローラーからの例外のみが@ExceptionHandlerにルーティングされます

ただし、@ControllerAdviceはグローバルです。例外やバインディングなどを一元的に処理することができます。これは、定義されているすべてのコントローラーに適用されます。

12
Jérémie B

違いは次のとおりです。例外処理コードを構成する必要がある場合は、プロジェクトで@ExceptionHandlerアノテーションを使用する必要があります。これは2つの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);
    }

コードに両方が存在する場合は、ローカルがグローバルのものよりも優先されます。理想的には、すべてのコントローラークラスにコードを追加する必要がないため、2番目のオプションの方が適しています。@ ControllerAdviceを使用したこのクラスは、コントローラーからdaoまでのコードが原因で発生するすべての例外のワンストップソリューションになります。コードの長さ。

6
Mohammed Amen

@ExceptionHandlerは、ローカルレベルまたはグローバルレベルで使用できます。ローカルレベルとは、コントローラー自体内でこのアノテーションを使用して、そのコントローラー内でのみ例外を処理することを意味します。そのコントローラーによってスローされたすべてのエラーは、その@ExceptionHandlerによってキャッチされます。ただし、これは、別のコントローラーに同様の例外がある場合、対応するコードをそのコントローラーでローカルに再度書き直す必要があることを意味します。

コントローラごとにこのスタイルの例外処理を繰り返さないようにするために、@ ControllerAdviceという別のアノテーションを使用して、グローバルレベルで@ExceptionHanlderを記述できます。

@ControllerAdviceは例外処理に固有のものではなく、グローバルレベルでのプロパティ、検証、またはフォーマッターバインディングの処理にも使用されます。例外処理のコンテキストでの@ControllerAdviceは、@ Exceptionhandlerアノテーションを使用してグローバルレベルで例外処理を行うもう1つの方法です。

HandlerExceptionResolverになりました-これは、より低いレベルのインターフェースです。 Springはこれの2つの実装を提供します:

  • ResponseStatusExceptionResolver:@ResponseStatusアノテーションのサポートをサポートします
  • ExceptionHandlerExceptionResolver:これは@ExceptionHandlerアノテーションをサポートします

例:したがって、例外を処理して例外処理戦略を選択する場合は、アノテーションを使用してローカルまたはグローバルの例外処理を選択することを考える必要があります。 HTTPステータスコードを提供する方法、@ Responseエンティティでそれをラップする方法など、ハンドラページにリダイレクトする方法、フラッシュ属性を介してデータを運ぶ方法、またはパラメータを取得する方法など。または、注釈をスキップして、 SimpleMappingExceptionResolverを開始し、特定の例外をエラーハンドラページのURLにマッピングします。

ここでは、より高いレベルで実装を処理し、これらのオプションに基づいて戦略を構築しているため、この段階では、より低いレベルの基になるHandlerExceptionResolverを考慮していません。

クエリに答えるための上記のコンテキスト-@ControllerAdviceは例外処理用に導入されていません。@ ExceptionHandlerを使用してグローバルに例外を処理するために利用できるメカニズムです。 HandlerExceptionResolverは、@ ResponseStatusおよび@Exceptionhandlerアノテーションのサポートに役立つ実装を持つインターフェースです。 Springフレームワークは適切な例外処理を提供しないため、MVCシステムに関連する例外を処理する必要がない限り。したがって、渡す必要がある場合は、最初の場所では到達しないため、コントローラによってキャッチされない不正な@Requestmappingなどに関連する問題が発生すると、HandlerExceptionResolverの実装が役立ちます。

2
Chetan Handa