티스토리 뷰
결론부터 말하자면 다음 두 개의 어노테이션을 사용하여 에러를 한 곳에서 처리가 가능하다.
- @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에서 처리하면 돼서 중복된 코드를 줄일 수 있다.
- 센트리 같은 작업 역시 한 곳에서 처리할 수 있어 편리하다.
'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
- JPA
- node.js
- 디자인패턴
- BAEKJOON
- 객체지향
- 이팩티브 자바
- kotest
- 디자인 패턴
- 이펙티브 자바
- C++
- kkoon9
- BOJ
- Spring Boot
- 클린 아키텍처
- 클린 코드
- programmers
- 백준
- 테라폼
- MSA
- AWS
- Java
- Olympiad
- 정규표현식
- Kotlin
- 코테
- 알고리즘
- Algorithm
- Spring
- 프로그래머스
- Effective Java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |