Back-end/Spring

[Spring] @RestControllerAdvice 사용해서 Controller 예외처리

shoney9254 2024. 2. 9. 21:15
반응형

1. @RestControllerAdvice 사용해서 Controller 예외처리

 

@RestControllerAdvice 어노테이션은 Spring Framework에서 예외 처리를 위해 사용되는 특별한 클래스에 붙이는 어노테이션입니다. 이 어노테이션을 사용하면 전역에서 발생할 수 있는 예외를 캡처하고, 공통된 예외 처리 로직을 적용하여 API 응답을 일관성 있게 관리할 수 있습니다. @RestControllerAdvice는 @ControllerAdvice에 @ResponseBody가 추가된 형태로, REST API 개발 시 JSON 등의 응답 바디를 직접 제어할 수 있게 해줍니다.

1-1. 동작 방식

  • Spring의 AOP(Aspect-Oriented Programming)를 이용하여, 애플리케이션의 컨트롤러 계층에서 발생하는 예외를 잡아낸 후, 지정된 예외 처리 로직에 따라 처리합니다.
  • @ExceptionHandler 어노테이션을 사용하여 특정 예외를 처리하는 메서드를 정의할 수 있습니다.
  • @RestControllerAdvice 어노테이션을 사용한 클래스는 애플리케이션 전역에서 발생하는 예외를 처리할 수 있는 공통의 예외 처리기 역할을 합니다.
  • 예외 처리 메서드는 예외 유형별로 다르게 정의할 수 있으며, 예외 발생 시 적절한 HTTP 상태 코드와 메시지를 응답으로 반환할 수 있습니다.

1-2. 전역 예외 처리기 구현

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.http.ResponseEntity;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public ResponseEntity<String> handleGenericException(Exception e) {
        // 모든 예외를 처리하고 500 Internal Server Error 반환
        return ResponseEntity
                .status(500)
                .body("Internal Server Error: " + e.getMessage());
    }

    @ExceptionHandler(value = NullPointerException.class)
    public ResponseEntity<String> handleNullPointerException(NullPointerException e) {
        // NullPointerException을 처리하고 400 Bad Request 반환
        return ResponseEntity
                .status(400)
                .body("Null Pointer Exception: " + e.getMessage());
    }

    @ExceptionHandler(value = CustomException.class)
    public ResponseEntity<String> handleCustomException(CustomException e) {
        // 사용자 정의 예외 처리
        return ResponseEntity
                .status(e.getStatusCode())
                .body("Custom Error: " + e.getMessage());
    }
}

이 예시에서는 세 가지 예외 처리 메서드를 정의하고 있습니다:

  1. Exception.class에 대한 처리: 모든 종류의 예외를 처리하며, HTTP 상태 코드 500을 반환합니다.
  2. NullPointerException.class에 대한 처리: NullPointerException을 처리하며, HTTP 상태 코드 400을 반환합니다.
  3. CustomException.class에 대한 처리: 사용자 정의 예외를 처리하며, 예외에 설정된 상태 코드와 메시지를 반환합니다.

@RestControllerAdvice를 사용함으로써 애플리케이션 전역에서 발생하는 예외를 효과적으로 관리할 수 있으며, API 응답의 일관성을 유지할 수 있습니다.

 


2. 상속 관계에서의 예외처리는 어떻게 되는 것일까?

 

Spring에서는 예외 처리 시 클래스 간의 상속 관계를 고려하여 더 구체적인 예외, 즉 자식 예외 클래스에 대한 처리기(**@ExceptionHandler**가 붙은 메서드)가 있을 경우, 그 처리기를 우선적으로 사용합니다. 이는 예외가 발생했을 때 더 세밀한 예외 처리를 가능하게 합니다.

예를 들어, **NullPointerException**이 **RuntimeException**의 자식 클래스인 경우, 두 예외 모두를 처리할 수 있는 **@ExceptionHandler**가 있다면 **NullPointerException**에 대한 처리기가 우선적으로 호출됩니다. 만약 해당하는 구체적인 예외를 처리하는 **@ExceptionHandler**가 없다면, 상위 클래스를 처리하는 **@ExceptionHandler**가 대신 호출됩니다.

이러한 방식은 예외를 더 정확하게 처리하고, 다양한 예외 상황에 대해 더 상세한 응답을 제공하는 데 유용합니다. 예외 클래스의 상속 구조를 이해하고 올바르게 활용하면, 예외 처리 로직을 효과적으로 구성할 수 있습니다.

 

2-1. 상속 관계에서의 예시

 

아래는 상속 관계에 있는 예외를 처리하는 간단한 예시입니다. 이 예시에서는 RuntimeException과 그 자식 예외인 ArithmeticException을 처리하는 방법을 보여줍니다. ArithmeticException이 발생하면, 더 구체적인 예외 처리기인 handleArithmeticException 메서드가 호출되며, RuntimeException이나 그 외의 자식 예외들이 발생할 경우 handleRuntimeException 메서드가 호출됩니다.

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.http.ResponseEntity;

@RestControllerAdvice
public class ExceptionHandlingController {

    // ArithmeticException 처리
    @ExceptionHandler(ArithmeticException.class)
    public ResponseEntity<String> handleArithmeticException(ArithmeticException e) {
        return ResponseEntity
                .badRequest()
                .body("Arithmetic Exception Occurred: " + e.getMessage());
    }

    // RuntimeException 및 그 자식들 처리 (ArithmeticException 제외)
    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> handleRuntimeException(RuntimeException e) {
        return ResponseEntity
                .status(500)
                .body("Runtime Exception Occurred: " + e.getMessage());
    }
}

이 예시에서는 다음과 같은 작동 방식을 확인할 수 있습니다:

  1. ArithmeticException 발생 시: handleArithmeticException 메서드가 호출되어 HTTP 상태 코드 400(Bad Request)과 함께 "Arithmetic Exception Occurred: [에러 메시지]"라는 응답 바디를 반환합니다.
  2. ArithmeticException 이외의 RuntimeException 발생 시: handleRuntimeException 메서드가 호출되어 HTTP 상태 코드 500(Internal Server Error)과 함께 "Runtime Exception Occurred: [에러 메시지]"라는 응답 바디를 반환합니다.

이 방식을 통해 애플리케이션에서 발생할 수 있는 다양한 예외 상황에 대해 더 세분화된 예외 처리를 구현할 수 있으며, 예외의 유형에 따라 적절한 응답을 제공할 수 있습니다.

반응형