103

で注釈が付けられた複数のクラスがあり@ControllerAdvice、それぞれに@ExceptionHandlerメソッドが含まれています。

Exceptionこれ以上特定のハンドラーが見つからない場合は、これを使用する必要があるという意図で処理します。

Exception悲しいことに、Spring MVCは、より具体的なケース (IOExceptionたとえば)ではなく、常に最も一般的なケース ( ) を使用しているようです。

これは、Spring MVC の動作を期待する方法ですか? 私はJerseyのパターンをエミュレートしようとしています。これは、各ExceptionMapper(同等のコンポーネント)を評価して、処理する宣言された型がスローされた例外からどれだけ離れているかを判断し、常に最も近い先祖を使用します。

4

7 に答える 7

107

Sotirios Delimanolis は彼の回答で非常に役に立ちました。さらに調査したところ、Spring 3.2.4 では、@ControllerAdvice アノテーションを検索するコードも @Order アノテーションの存在をチェックし、ControllerAdviceBeans のリストをソートすることがわかりました。

@Order アノテーションのないすべてのコントローラーの結果のデフォルトの順序は Ordered#LOWEST_PRECEDENCE です。これは、最低の優先度にする必要があるコントローラーが 1 つある場合、すべてのコントローラーの順序を高くする必要があることを意味します。

UserProfileException または RuntimeException が発生したときに適切な応答を提供できる ControllerAdvice アノテーションと Order アノテーションを持つ 2 つの例外ハンドラー クラスを用意する方法を示す例を次に示します。

class UserProfileException extends RuntimeException {
}

@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
class UserProfileExceptionHandler {
    @ExceptionHandler(UserProfileException)
    @ResponseBody
    ResponseEntity<ErrorResponse> handleUserProfileException() {
        ....
    }
}

@ControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE)
class DefaultExceptionHandler {

    @ExceptionHandler(RuntimeException)
    @ResponseBody
    ResponseEntity<ErrorResponse> handleRuntimeException() {
        ....
    }
}
  • ControllerAdviceBean#initOrderFromBeanType() を参照してください。
  • ControllerAdviceBean#findAnnotatedBeans() を参照してください
  • ExceptionHandlerExceptionResolver#initExceptionHandlerAdviceCache() を参照してください。

楽しみ!

于 2013-12-09T14:47:08.657 に答える
3

同様の状況が、Spring ブログの優れた「 Spring MVC での例外処理」投稿のGlobal Exception Handlingというタイトルのセクションに記載されています。彼らのシナリオには、例外クラスに登録されている ResponseStatus 注釈をチェックし、存在する場合は例外を再スローしてフレームワークに処理させることが含まれます。この一般的な戦術を使用できる場合があります。より適切なハンドラーが存在するかどうかを判断して、再スローしてください。

あるいは、代わりに検討できる例外処理戦略が他にもいくつかあります。

于 2013-12-03T22:55:08.810 に答える