티스토리 뷰

결론부터 말하자면 다음 두 개의 어노테이션을 사용하여 에러를 한 곳에서 처리가 가능하다.

  • @RestControllerAdvice
  • @ExceptionHandler

먼저 ControllerAdvice 어노테이션을 살펴보자.

🐻
아래 내용은 모두 spring docs에 있는걸 나름대로 해석한 것입니다.

 

@RestControllerAdvice

@ControllerAdvice 및 @ResponseBody로 주석이 붙은 편리한 주석이다.

@ExceptionHandler 어노테이션이 붙은 메서드는 기본적으로 @ResponseBody의 의미를 가정하여 이 주석을 전송하는 유형은 컨트롤러 advice로 취급된다.

@RestControllerAdvice에서 사용되는 @ControllerAdvice과 @ResponseBody를 간단하게 살펴보자.

@ControllerAdvice

여러 @Controller 어노테이션이 붙은 클래스에서 공유하는 @ExceptionHandler, @InitBinder 또는 @ModelAttribute 메서드를 선언하는 클래스들의 @Component의 어노테이션이다.

@ControllerAdvice를 동반한 클래스들은 Spring bean으로 명시적으로 선언하거나 classpath를 통해 자동 검출할 수 있다.

이러한 모든 bean은 AnnotationAwareOrderComparator(@Order 및 Ordered)를 통해 정렬되며 RUNTIME에 해당 순서로 적용된다.

예외 처리의 경우 첫 번째 advice에서 일치하는 예외 핸들러 메서드를 사용하여 @ExceptionHandler가 선택된다.

@ResponseBody

web response body에 바인딩되는 메서드의 반환 값을 나타내는 어노테이션이다.

@ExceptionHandler 같은 handler 어노테이션이 붙은 메서드를 지원한다.

🐻
error가 발생하면 Filter와 Servlet을 거쳐 개발자가 정의해놓은 GlobalExceptionHandler로 가게 되는데,
이 부분은 다른 포스팅에서 더욱 자세히 다뤄보자.

 

@ExceptionHandler

특정 핸들러 클래스 또는 핸들러 메서드에서 예외를 처리하기 위한 어노테이션이다.

이 어노테이션이 달린 핸들러 메서드는 매우 유연한 시그니처를 가질 수 있다.

다음 유형의 매개 변수를 임의 순서로 가질 수 있다.

An exception argument

일반 예외 또는 보다 구체적인 예외로 선언된다.

주석 자체가 예외 유형을 값()으로 좁히지 않는 경우에도 매핑 힌트 역할을 한다.

// example
@ExceptionHandler(HttpMessageNotReadableException.class)

Request, response objects (typically from the Servlet API).

ex) javax.servlet.ServletRequest, javax.servlet.http.HttpServletRequest

Session object

ex) javax.servlet.http.HttpSession

핸들러 방식에서는 다음 return type이 지원된다.

  • Servlet MVC
  • org.springfromework.ui.Model Object
  • java.util.Map
  • org.springfromework.ui.View Object
  • String
  • @ResponseBody 어노테이션이 붙은 메서드
  • HttpEntity<?> 혹은 ResponseEntity<?>

예시 코드는 다음과 같다.

@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * HttpMessageNotReadableException
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    protected ResponseEntity<ErrorResponse> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        requestErrorLogging(e);
        log.error("HttpMessageNotReadableException", e);
        ErrorResponse errorResponse = new ErrorResponse(HttpStatus.SC_BAD_REQUEST, "입력 값을 확인해주세요. 올바르지 않은 형식의 데이터가 포함되어 있습니다. ");
        return ResponseEntity.ok().body(errorResponse);
    }
}

잘못된 request 요청을 보내면 마지막에는 위 익셉션 핸들러로 거치게 된다.

global exception handler의 장점

내가 생각하는 장점은 다음과 같다.

  • 에러를 한 곳에서 관리하면 중복된 코드를 줄일 수 있다.
    • log4j2를 통한 에러 로그 관리 등을 GlobalExceptionHandler에서 처리하면 돼서 중복된 코드를 줄일 수 있다.
  • 센트리 같은 작업 역시 한 곳에서 처리할 수 있어 편리하다.

 

 

Spring Boot에 Sentry 끼얹기 [1]

회사에서 진행한 프로젝트에 sentry를 연동하면서 정리한 글이다. 프로젝트에서는 Gradle을 사용했으며, Spring boot 2.1.0, log4j2를 사용했다. 먼저 Spring boot 2.1.0 버전부터 지원을 한다. 위 버전 아래는

kkoon9.tistory.com

 

'Sping Framework' 카테고리의 다른 글

Spring Cloud Sleuth [2] - 분산 시스템과 동작 과정  (0) 2022.04.06
Spring Cloud Sleuth [1] - 용어  (0) 2022.04.04
Spring Boot에 Sentry 끼얹기 [2]  (1) 2022.04.03
Spring Boot에 Sentry 끼얹기 [1]  (0) 2022.03.26
Mono [1]  (0) 2022.02.04
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함