ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Boot - @ControllerAdvice, @ExceptionHandler를 활용한 전역 예외 처리
    Framework & Library/Spring Boot 2022. 2. 11. 18:28

    예외 처리

    예외 클래스

     

    ㆍ 모든 Exception 클래스는 Throwable 클래스를 상속받고 있다.

     

      Checked Exception Uncheked Exception
    처리여부 반드시 예외 처리 필요 명시적 처리 강제하지 않음
    확인시점 컴파일 단계 실행 중 단뎨
    예외 발생 시 트랜잭션 롤백 수행하지 않음 롤백 수행
    대표 예외 1. IOException
    2. SQLException
    1. NullPointerException
    2. IllegalArgumentException
    3. IndexOutOfBoundException
    4. SystemException

    ㆍ Exception 클래스는 수많은 자식 클래스가 있으며, 크게 Checked Exception과 Unchecked Exception으로 나눌 수 있다.

     

    Spring Boot의 예외 처리 방식

     

    애너테이션 설명
    @ControllerAdvice 모든 Controller에서 발생할 수 있는 Exception을 전역으로 처리하기 위해 사용
    @ExceptionHandler 컨트롤러 내 특정 Exception을 처리하기 위한 애너테이션

    ㆍ Spring Boot의 예외 처리 방식은 위와 같은 크게 두 가지가 존재한다.

     

    1. @ControllerAdvice, @RestControllerAdvice

    ㆍ "@ControllerAdvice" 애너테이션은 Spring에서 제공하는 애너테이션이다.

    ㆍ "@Controller"나 "@RestController"에서 발생하는 예외를 한 곳에서 관리하고 처리할 수 있게 하는 애너테이션이다.

    ㆍ 설정을 통해 범위 지정이 가능하며, 디폴트 값으로 모든 Controller에 대해 예외 처리를 관리한다.

    ㆍ 예외 발생 시 JSON 형태로 결과를 반환하기 위해 "@RestControllerAdvice"를 사용할 수 있다.

     

    2. @ExceptionHandler

    ㆍ 예외 처리 상황이 발생하면 해당 Handler로 처리하겠다고 명시하는 애너테이션이다.

    ㆍ 애너테이션 뒤에 괄호를 붙여 어떤 ExceptionClass를 처리할지 설정할 수 있다. ex) @ExceptionHandler(OOException.class)

    ㆍ Exception.class는 최상위 클래스로 하위 세부 예외 처리 클래스로 설정한 핸들러가 존재하면 해당 핸들러가 우선 처리하게 되며, 처리되지 못하는 예외 처리에 대해 Exception.class에서 핸들링한다.

    ㆍ "@ControllerAdvice"로 설정된 클래스 내에서 메서드로 정의할 수 있지만, 각 Controller 안에서도 설정이 가능하다. 이 경우 전역 설정(@ControllerAdvice)보다 지역 설정(Controller)으로 정의한 핸들러가 높은 우선순위를 가진다.


    @ControllerAdvice, @RestControllerAdvice 적용

    GlocalExceptionHandler 클래스 생성
    @RestControllerAdvice
    public class GlobalExceptionHandler {
    
        private final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    
        @ExceptionHandler(value = Exception.class)
        public ResponseEntity<Map<String, String>> ExceptionHandler(Exception e) {
            HttpHeaders responseHeaders = new HttpHeaders();
            HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
    
            LOGGER.info(e.getLocalizedMessage());
            LOGGER.info("GlobalExceptionHandler 내 ExceptionHandler() 호출");
    
            Map<String, String> map = new HashMap<>();
            map.put("error type", httpStatus.getReasonPhrase());
            map.put("code", "400");
            map.put("message", "에러 발생");
    
            return new ResponseEntity<>(map, responseHeaders, httpStatus);
        }
    }

    ㆍ 위 클래스는 Controller에서 발생한 예외를 처리하기 위한 클래스이다.

    ㆍ 모든 Controller에서 발생한 예외는 GlobalExceptionHandler 내 ExceptionHandler() 메서드를 통해 처리된다.

     

    HelloController 클래스 수정
    @PostMapping("/exception")
    public void exceptionTest() throws Exception {
        throw new Exception();
    }

    ㆍ HelloController 클래스 내에 고의적으로 예외를 발생시키기 위한 exceptionTest() 메서드를 생성한다.


    테스트

    예외 발생

     

    ㆍ 예외를 발생시키기 위해 서버로부터 요청을 한다.

     

    예외 처리 확인

     

    ㆍ 발생한 예외가 GlobalExceptionHandler 클래스에 의해 처리되는 것을 확인할 수 있다.

     

    ExceptionHandler() 메서드 추가
    @ExceptionHandler(value = Exception.class)
    public ResponseEntity<Map<String, String>> ExceptionHandler(Exception e) {
        HttpHeaders responseHeaders = new HttpHeaders();
        HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
    
        LOGGER.info(e.getLocalizedMessage());
        LOGGER.info("Controller 내 ExceptionHandler() 호출");
    
        Map<String, String> map = new HashMap<>();
        map.put("error type", httpStatus.getReasonPhrase());
        map.put("code", "400");
        map.put("message", "에러 발생");
    
        return new ResponseEntity<>(map, responseHeaders, httpStatus);
    }

    ㆍ HelloController 클래스에 위 코드와 같은 ExceptionHandler() 메서드를 추가한다.

    ㆍ 예외 처리가 발생했을 때 어떤 핸들러가 높은 우선순위를 가지는지 확인하기 위한 용도이다.

     

    예외 발생

     

    ㆍ 예외를 발생시키기 위해 서버로부터 요청을 한다.

     

    예외 처리 확인

     

    ㆍ 발생한 예외가 HelloController 내 ExceptionHandler() 메서드에 의해 처리되는 것을 확인할 수 있다.

    ㆍ 전역 설정(@ControllerAdvice)보다 지역 설정(Controller)으로 정의한 핸들러가 높은 우선순위를 가진다는 것을 확인하였다.


     

    GitHub - qlsdud0604/spring-boot-study

    Contribute to qlsdud0604/spring-boot-study development by creating an account on GitHub.

    github.com

     

    728x90

    'Framework & Library > Spring Boot' 카테고리의 다른 글

    Spring Boot - JUnit이란?  (0) 2022.03.13
    Spring Boot - Custom Exception  (0) 2022.02.14
    Spring Boot - 유효성 검사  (0) 2022.02.10
    Spring Boot - Logback 적용하기  (0) 2022.02.09
    Spring Boot - ORM이란?  (0) 2022.02.03

    댓글

Designed by Tistory.