해당글은 공식문서를 직역한 부분이 많아 문장이 어색할 수 있습니다. 오역이 있을 시 언제든 지적해주시면 감사하겠습니다 🙇🏻♀️
들어가기전에 Exception에 대해 짤막하게 정리하고자 한다.
(분량이 많아 정말 최소한으로 가볍게하고 다음에 Exception 정리 포스팅..예정..)
우리가 개발하면서 마주치게 되는 Exception들을 처리하기 위해 Exception Handler와 Controller Advice를 사용할 수 있는데 이 둘의 개념을 학습하면서 간단히 아래처럼 정리해보았다.
@Controller
와 @ControllerAdvice
클래스들은 Controller 메소드들로부터 발생한 exception들을 처리하기 위해 @ExceptionHandler
메소드를 갖는다.
예시)
@Controller
public class SimpleController {
// ...
@ExceptionHandler
public ResponseEntity<String> handle(IOException ex) {
// ...
}
}
특정 타입의 exception을 잡고 싶은 경우에는 아래의 예시처럼 (@ExceptionHandler({FileSystemException.class, RemoteException.class})
) 작성하면 특정 Exception 하나 또는 Exception 여러개를 잡을 수 있다. 이 때 value를 넣어주지 않으면 모든 Exception을 잡는다.
스프링 공식문서에서는 Exception들을 구체적으로 명시하기를 권하고 있다.
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handle(IOException ex) {
// ...
}
@ExceptionHandler
, @InitBuilder
그리고 @ModelAttribute
메소드들은 @Controller
클래스 이거나 해당 클래스 계층에서만 적용이 가능하다.
하지만@ControllerAdvice
또는 @RestControllerAdvice
를 사용하면 어떤 컨트롤러에나 적용이 가능하다.
(= ExceptionHandler 사용해서 Exception을 핸들링 할 수 있다는 이야기)
또한 5.3 버전에서는 @Controller
가 있으면 Exception을 핸들링하기 위해 @ControllerAdvice
가 가지고 있는@ExceptionHandler
메소드들이 사용될 수 있다.
요약: 어플리케이션에 같은 에러를 핸들링 하는 것을 가능하게 하는 인터셉터
@ControllerAdvice
는 컴포넌트 스캐닝을 통해 스프링 빈으로 등록될 수 있는 @Component
의 메타 어노테이션이다.
@RestControllerAdvice
는 @ControllerAdvice
와 @ResponseBody
의 메타 어노테이션이다. 그렇기 때문에 @ExceptionHandler
가 response body로 렌더링 된 리턴 값을 갖는다.
Spring Security Exception
(예시, runtime exception에 속하는 AuthenticationException과 AccessDeniedException)들은 핸들링 할 수 없다.
DispatcherServlet과 컨트롤러 메소드들이 불러지기 전에 authentication filter에 의해 exception이 던져지기 때문이다. 이 같은 exception들을 @ExceptionHandler
와 @ControllerAdvice
로 핸들링하기 위해서는 AuthenticationEntryPoint를 커스텀해야한다.
자세한 내용은 baeldung의 spring security exceptionhandler 참고.
프로젝트 진행 중 아래와 같이 작성해보았다.
아직 커스텀 예외들을 작성하지 않아 일단은 RuntimeException을 잡는 것으로 작성해두었는데 작동은 잘 하는 것으로 보인다.
하지만 이렇게 쓰면 예외가 발생 했을 때 정확히 어떤 예외가 발생했는지 확인이 어려워 해당 부분은 주석 처리해두고 프로젝트를 진행하면서 이후에 예외상황들을 좀 더 세세하게 나누어(스프링 공식문서에서 권장하듯이) 해당 클래스를 구현할 계획이다.
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-exceptionhandler
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html
https://www.baeldung.com/spring-security-exceptionhandler
오.. 마침 스프링 예외처리에 대해서 공부를 하려고 했는데 어떻게 아시고 정리를 해주셧나요!! 👍
ExceptionHandler만으로는 컨트롤러 계층에서 발생한 예외만 처리되는 걸 처음 알았네요.
공식문서로 공부하는 거 정말 멋집니다. 저도 앞으로는.. 공식문서 공부 해야겠네요. 홧팅!!