2022.09.01 - [SPRING] - [SPRING] AOP 개념
매번 코드를 짤때마다 그리고 유효성 검증을 추가할때마다 try/catch 문을 사용하다보니 가독성이 낮아지는 게 느껴졌다.
다들 어떻게 저렇게 깔끔하게 짜는 걸까 했는데 전역 예외처리를 했기 때문이었다.
이를 위해서 알아야 할 개념
- @ControllerAdvice 와 @RestControllerAdvice
- @ExceptionHandler
- Spring의 예외 처리 흐름
@ControllerAdvice 와 @RestControllerAdvice
- @ControllerAdvice
- 클래스에 선언만 하면 됨
- 모든 @Controller에 대한 전역적 예외를 잡아서 처리
- @Component가 선언되어있어 Bean으로 관리 되어 사용
- @RestControllerAdvice
- @ControllerAdvice + @ResponseBody
- @ResponseBody 를 따로 붙여주지 않아도 객체 리턴함
@ExceptionHandler
- 메소드에 선언하고 특정 예외 클래스를 지정해주면 해당 예외 발생 시 메소드에 정의한 로직을 처리 가능
- 즉, 내가 처리하고 싶은 Exception을 정의한다음 (CustomException) 해당 예외 발생 시 원하는 대로 처리가 가능
- Exception 클래스들을 속성으로 받아 처리할 예외를 지정
- @ResponseStatus와 달리 에러 응답(payload)을 자유롭게 다룰 수 있다는 점에서 유연하다
Spring의 예외 처리 흐름
- 예외가 발생하면 HandlerExceptionResolver가 동작하고 HandlerInterceptor를 통해서 DispatcherServlet을 통해 Response가된다
- HandlerExceptionResolver가 동작함
- 예외가 발생한 컨트롤러 안에 적합한 @ExceptionHandler가 있는지 검사함
- 컨트롤러의 @ExceptionHandler에서 처리가능하다면 처리하고, 그렇지 않으면 ControllerAdvice로 넘어감
- ControllerAdvice안에 적합한 @ExceptionHandler가 있는지 검사하고 없으면 다음 처리기로 넘어감
- ResponseStatusExceptionResolver가 동작함
- @ResponseStatus가 있는지 또는 ResponseStatusException인지 검사함
- 맞으면 ServletResponse의 sendError()로 예외를 서블릿까지 전달되고, 서블릿이 BasicErrorController로 요청을 전달함
- DefaultHandlerExceptionResolver가 동작함
- Spring의 내부 예외인지 검사하여 맞으면 에러를 처리하고 아니면 넘어감
- 적합한 ExceptionResolver가 없으므로 예외가 서블릿까지 전달되고, 서블릿은 SpringBoot가 진행한 자동 설정에 맞게 BasicErrorController로 요청을 다시 전달함
써먹어 보기
- 기존에 만들어 둔 CustomException Class
@Getter
public class CustomErrorException extends RuntimeException {
private final ErrorCode errorCode;
public CustomErrorException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
}
- RuntimeException을 상속 받아 ErrorCode를 출력한다.
- GlobalExceptionHandler
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler
public ResponseEntity<ResponseDto<?>> customExceptionHandler(CustomErrorException exception) {
log.error(exception.getMessage());
return new ResponseEntity<>(ResponseDto.fail(exception.getErrorCode()), HttpStatus.BAD_REQUEST);
}
}
👉 ResponseEntity<Object> 객체는 HTTP Status를 다르게해 Client에게 보낼때 사용하는 객체이다. 보낼 Object와 두 번째 인자로 아래와 같이 HTTP Status를 지정할 수 있다.
~ 끝 ~
...... handler 클래스 하나만으로 그동안에 계속 해왔던 try catch 문을 삭제해도 예외처리가 가능해졌다.
- Before - Controller
- After - Controller
한결 가독성이 좋아진걸 확인할 수 있다.
'🌿SPRING > 🌱연습[SPRING]' 카테고리의 다른 글
[SPRING][JPA] Paging/Pagination - Pageable 객체 받아 사용하기 (0) | 2022.10.11 |
---|---|
[SPRING] JWT Exception (0) | 2022.10.06 |
[SPRING] 모임 태그 - 태그 수정하기 (2) + bug fix (0) | 2022.09.28 |
[SPRING] 모임 태그 - 생성 시 태그 같이 넣기 (1) (0) | 2022.09.28 |
[SPRING] [AWS] 게시글 이미지 업로드 하기 (3) - 이미지 수정,삭제하기 + bug fix (0) | 2022.09.23 |