グローバル例外の処理


Springでの異常処理方法はいろいろあります.方法はtry/catch処理を用いてもよいし、コントローラ内の異常を@ExceptionHandler処理してもよい.しかし、グローバルに発生した異常をどのように処理するかを理解する必要があります.
グローバルでの例外の処理
まず、なぜグローバルで例外処理を行うのですか?@ExceptionHandlerを使用してコントローラに異常処理を行います.
@RestController
public class LineController {

    // ...

    @GetMapping("/lines")
    public ResponseEntity<List<LineResponse>> getLines() {
        // ...
    }
    
    @PostMapping("/lines")
    public ResponseEntity<LineResponse> createLine(@RequestBody LineRequest lineRequest) {
        // ...
    }
    
    @ExceptionHandler(LineException.class)
    public ResponseEntity<ErrorResponse> handleLineException(final LineException error) {
        // ...
    }
    
}
コントローラに発生した異常はhandleLineExceptionメソッドで処理できます.しかし、コントローラが増えたら?コントローラの増加に伴い、異常処理に対する重複コードも増加し、大量のコードが関連する.このようにメンテナンスも難しくなります.
but!!
グローバル例外処理は、上記の問題を解決することができる.
だから全境はどのように例外を処理しますか?@ControllerAdviceまたは@RestControllerAdviceを使用してグローバル例外処理を行います.
  • @RestControllerAdvice@ControllerAdvice+@ResponseBodyである.(感覚像@Controller@RestController)
  • 次に、アプリケーション内のすべてのコントローラの例外を1つの場所で管理できる、態様向けのプログラミング(AOP)です.
    どのように使いますか.
    @RestControllerAdvice
    public class GlobalExceptionHandler {
    
        @ExceptionHandler(LineException.class)
        public ResponseEntity<ErrorResponse> handleLineException(final LineException error) {
            // ...
        }
        
        // ...
    }
    コントローラで発生したすべての異常は、@RestControllerAdviceによってキャプチャされ、@ExceptionHandlerによって個別にキャプチャされ、処理されます.
    私は全局の異常を処理する時、この点に興味を持っています.
    では、@Controllerの例外は@ControllerAdviceの例外は@RestControllerの例外ですか?
    いいえ.@RestControllerAdviceで異常が発生した場合は@Controllerでキャプチャすることができ、@RestControllerAdviceで異常が発生した場合は@RestControllerで異常をキャプチャすることができる.
    コントローラに@ControllerAdviceが追加されましたが、グローバルExceptionHandlerにRestControllerが誤って追加されました.しかし、GlobalExceptionHandlerはコントローラの例外を発見した.
    理由は何ですか.@ControllerAdvice@RestControllerは何ですか?
  • @RestControllerAdvice = @RestController + @Controller
  • @ResponseBody = @RestControllerAdvice + @ControllerAdvice
  • 簡単に言えば、@ResponseBodyおよび@RestControllerは、@RestControllerAdviceおよび@Controller@ControllerAdviceが追加されただけである.
    // @RestController
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Controller
    @ResponseBody
    public @interface RestController {
        // ...
    }
    
    // @RestControllerAdvice
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @ControllerAdvice
    @ResponseBody
    public @interface RestControllerAdvice {
        // ...
    }
    したがって,互いに例外を排除することができる.ただし@ResponseBody@RestControllerAdviceと同様に@RestControllerもあり、JavaオブジェクトをJson/Xml形式に戻し、HTTP応答Bodyに入れることができる.
    では、@ResponseBodyで発生した異常のみを受信@RestControllerAdviceで受信できますか?
    もちろんあります.@RestControllerを使用する場合、@RestControllerAdviceを設定すると、@RestControllerAdvice(annotations = RestController.class)に異常が発生するだけです.@RestControllerもそうです.
    参考資料
    「Spring Boot」(Spring Boot)エラー処理: