본문 바로가기

Spring Boot

[Spring Boot] @ControllerAdvice 중앙 집중식 예외 처리

728x90

 

Spring Framework를 사용하여 웹 애플리케이션을 개발할 때, 예외 처리는 중요한 부분입니다. 특히, 모든 컨트롤러에서 발생할 수 있는 예외를 일관되게 처리하는 것은 유지보수성과 코드의 가독성을 높이는 데 큰 도움이 됩니다. 이를 위해 Spring은 @ControllerAdvice 어노테이션을 제공합니다.

@ControllerAdvice란?

@ControllerAdvice는 Spring MVC에서 컨트롤러 전반에 걸쳐 예외를 처리할 수 있도록 도와주는 어노테이션입니다. 이는 특정 컨트롤러에 종속되지 않고, 전역적으로 적용되므로 여러 컨트롤러에서 발생하는 예외를 한 곳에서 관리할 수 있습니다.

주요 기능

  1. 예외 처리: 특정 예외를 처리하는 메서드를 정의할 수 있습니다.
  2. 글로벌 바인딩/유효성 검사: 모든 컨트롤러에 적용되는 데이터 바인딩과 유효성 검사를 설정할 수 있습니다.
  3. 모델 속성 설정: 모든 컨트롤러에 공통적으로 사용되는 모델 속성을 정의할 수 있습니다.

 

@ExceptionHandler와의 관계

@ExceptionHandler는 개별 컨트롤러 클래스 내에서 예외를 처리하는 데 사용됩니다. 반면, @ControllerAdvice는 애플리케이션 전반에 걸쳐 예외를 처리합니다. 이는 전역적으로 일관된 예외 처리를 구현하는 데 유용합니다.

예제 코드

1. @ControllerAdvice 정의

먼저, @ControllerAdvice 어노테이션을 사용하여 예외 처리 로직을 담은 클래스를 정의합니다.

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String handleResourceNotFoundException(ResourceNotFoundException ex) {
        return "error/404";
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String handleGenericException(Exception ex) {
        return "error/500";
    }
}

위 예제에서 GlobalExceptionHandler 클래스는 @ControllerAdvice를 사용하여 정의되었으며, 두 가지 예외를 처리합니다:

  • ResourceNotFoundException 예외가 발생하면 404 오류 페이지를 반환합니다.
  • 그 외의 일반적인 예외가 발생하면 500 오류 페이지를 반환합니다.

 

2. 커스텀 예외 정의

이제 ResourceNotFoundException 예외를 정의해보겠습니다.

public class ResourceNotFoundException extends RuntimeException {

    public ResourceNotFoundException(String message) {
        super(message);
    }
}

이 예외는 리소스를 찾을 수 없을 때 발생시키는 커스텀 예외입니다.

 

3. 컨트롤러에서 예외 발생

컨트롤러에서 특정 조건에 따라 예외를 발생시킵니다.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/resource/{id}")
    public String getResource(@PathVariable String id) {
        if ("notfound".equals(id)) {
            throw new ResourceNotFoundException("Resource not found with id: " + id);
        }
        return "Resource content";
    }
}

이제 /resource/notfound 경로로 접근하면 ResourceNotFoundException이 발생하고, GlobalExceptionHandler에서 정의한 404 오류 페이지가 반환됩니다.

 

결론

@ControllerAdvice는 Spring MVC 애플리케이션에서 전역적으로 예외를 처리하는 강력한 방법을 제공합니다. 이를 활용하면 모든 컨트롤러에 일관된 예외 처리 로직을 적용할 수 있으며, 코드의 재사용성과 유지보수성을 크게 향상시킬 수 있습니다.