-
Spring Boot - @ControllerAdvice, @ExceptionHandler를 활용한 전역 예외 처리Framework & Library/Spring Boot 2022. 2. 11. 18:28
예외 처리
예외 클래스
ㆍ 모든 Exception 클래스는 Throwable 클래스를 상속받고 있다.
Checked Exception Uncheked Exception 처리여부 반드시 예외 처리 필요 명시적 처리 강제하지 않음 확인시점 컴파일 단계 실행 중 단뎨 예외 발생 시 트랜잭션 롤백 수행하지 않음 롤백 수행 대표 예외 1. IOException
2. SQLException1. 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