web-dev-qa-db-ja.com

Spring Webフラックスで@ExceptionHandlerをどのように使用できますか?

春のwebでは、コントローラーのサーバーおよびクライアントエラーを処理するために@ExceptionHandlerアノテーションを使用できます。

私はこの注釈をweb-fluxコントローラーで使用しようとしましたが、それでもうまくいきましたが、調査の結果、次のことがわかりました here

Spring Web Reactiveの状況はさらに複雑です。リアクティブストリームは、コントローラーメソッドを実行するスレッドとは別のスレッドによって評価されるため、例外がコントローラースレッドに自動的に伝達されることはありません。つまり、@ ExceptionHandlerメソッドは、リクエストを直接処理するスレッドでスローされる例外に対してのみ機能します。 @ExceptionHandler機能を使用する場合は、ストリームでスローされた例外をスレッドに伝播する必要があります。これは少し落ち込んでいるように見えますが、執筆時点では、このSpring 5はまだリリースされていないため、エラー処理が改善される可能性があります。

だから私の質問は、例外をスレッドに戻す方法です。 @ExceptionHandlerとSpring Webフラックスの使用に関する良い例や記事はありますか?

更新: spring.io からサポートされているようですが、一般的な理解が不足しています

おかげで、

6
Evgen

@ExceptionHandlerアノテーション付きメソッドを使用して、WebFluxハンドラーの実行中に発生するエラー(コントローラーメソッドなど)を処理できます。 MVCを使用すると、マッピング段階で発生するエラーを実際に処理することもできますが、WebFluxの場合はそうではありません。

例外伝播の質問に戻りますが、共有している記事は正確ではありません。

事後対応型アプリケーションでは、要求処理は確かにいつでも1つのスレッドから別のスレッドにホップできるため、「要求ごとに1つのスレッド」モデルに依存することはできなくなります(ThreadLocalと考えてください)。

実際には、例外の伝播やスレッドの管理方法について考える必要はありません。たとえば、次のサンプルは同等である必要があります。

@GetMapping("/test")
public Mono<User> showUser() {
  throw new IllegalStateException("error message!);
}


@GetMapping("/test")
public Mono<User> showUser() {
  return Mono.error(new IllegalStateException("error message!));
}

Reactorは、Reactive Streamsコントラクトで期待されるように、これらの例外をエラー信号として送信します(詳細については、「 「エラー処理」のドキュメントセクション を参照してください)。

7
Brian Clozel

元の質問に対する正確な回答ではありませんが、例外をhttp応答ステータスにマッピングする簡単な方法は、org.springframework.web.server.ResponseStatusException /をスローするか、独自のサブクラスを作成することです...

Http応答ステータス+スプリングを完全に制御すると、reasonを追加するオプションを含む応答本文が追加されます。

{
    "timestamp": 1529138182607,
    "path": "/api/notes/f7b.491bc-5c86-4fe6-9ad7-111",
    "status": 400,
    "error": "Bad Request",
    "message": "For input string: \"f7b.491bc\""
}
3
Hartmut